instance.ts 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import {
  2. extend,
  3. looseEqual,
  4. looseIndexOf,
  5. looseToNumber,
  6. NOOP,
  7. toDisplayString
  8. } from '@vue/shared'
  9. import {
  10. ComponentPublicInstance,
  11. PublicPropertiesMap
  12. } from '../componentPublicInstance'
  13. import { getCompatChildren } from './instanceChildren'
  14. import {
  15. DeprecationTypes,
  16. assertCompatEnabled,
  17. isCompatEnabled
  18. } from './compatConfig'
  19. import { off, on, once } from './instanceEventEmitter'
  20. import { getCompatListeners } from './instanceListeners'
  21. import { shallowReadonly } from '@vue/reactivity'
  22. import { legacySlotProxyHandlers } from './componentFunctional'
  23. import { compatH } from './renderFn'
  24. import { createCommentVNode, createTextVNode } from '../vnode'
  25. import { renderList } from '../helpers/renderList'
  26. import {
  27. legacyBindDynamicKeys,
  28. legacyBindObjectListeners,
  29. legacyBindObjectProps,
  30. legacyCheckKeyCodes,
  31. legacyMarkOnce,
  32. legacyPrependModifier,
  33. legacyRenderSlot,
  34. legacyRenderStatic,
  35. legacyresolveScopedSlots
  36. } from './renderHelpers'
  37. import { resolveFilter } from '../helpers/resolveAssets'
  38. import { InternalSlots, Slots } from '../componentSlots'
  39. import { ContextualRenderFn } from '../componentRenderContext'
  40. import { resolveMergedOptions } from '../componentOptions'
  41. export type LegacyPublicInstance = ComponentPublicInstance &
  42. LegacyPublicProperties
  43. export interface LegacyPublicProperties {
  44. $set(target: object, key: string, value: any): void
  45. $delete(target: object, key: string): void
  46. $mount(el?: string | Element): this
  47. $destroy(): void
  48. $scopedSlots: Slots
  49. $on(event: string | string[], fn: Function): this
  50. $once(event: string, fn: Function): this
  51. $off(event?: string | string[], fn?: Function): this
  52. $children: LegacyPublicProperties[]
  53. $listeners: Record<string, Function | Function[]>
  54. }
  55. export function installCompatInstanceProperties(map: PublicPropertiesMap) {
  56. const set = (target: any, key: any, val: any) => {
  57. target[key] = val
  58. return target[key]
  59. }
  60. const del = (target: any, key: any) => {
  61. delete target[key]
  62. }
  63. extend(map, {
  64. $set: i => {
  65. assertCompatEnabled(DeprecationTypes.INSTANCE_SET, i)
  66. return set
  67. },
  68. $delete: i => {
  69. assertCompatEnabled(DeprecationTypes.INSTANCE_DELETE, i)
  70. return del
  71. },
  72. $mount: i => {
  73. assertCompatEnabled(
  74. DeprecationTypes.GLOBAL_MOUNT,
  75. null /* this warning is global */
  76. )
  77. // root mount override from ./global.ts in installCompatMount
  78. return i.ctx._compat_mount || NOOP
  79. },
  80. $destroy: i => {
  81. assertCompatEnabled(DeprecationTypes.INSTANCE_DESTROY, i)
  82. // root destroy override from ./global.ts in installCompatMount
  83. return i.ctx._compat_destroy || NOOP
  84. },
  85. // overrides existing accessor
  86. $slots: i => {
  87. if (
  88. isCompatEnabled(DeprecationTypes.RENDER_FUNCTION, i) &&
  89. i.render &&
  90. i.render._compatWrapped
  91. ) {
  92. return new Proxy(i.slots, legacySlotProxyHandlers)
  93. }
  94. return __DEV__ ? shallowReadonly(i.slots) : i.slots
  95. },
  96. $scopedSlots: i => {
  97. assertCompatEnabled(DeprecationTypes.INSTANCE_SCOPED_SLOTS, i)
  98. const res: InternalSlots = {}
  99. for (const key in i.slots) {
  100. const fn = i.slots[key]!
  101. if (!(fn as ContextualRenderFn)._ns /* non-scoped slot */) {
  102. res[key] = fn
  103. }
  104. }
  105. return res
  106. },
  107. $on: i => on.bind(null, i),
  108. $once: i => once.bind(null, i),
  109. $off: i => off.bind(null, i),
  110. $children: getCompatChildren,
  111. $listeners: getCompatListeners
  112. } as PublicPropertiesMap)
  113. /* istanbul ignore if */
  114. if (isCompatEnabled(DeprecationTypes.PRIVATE_APIS, null)) {
  115. extend(map, {
  116. // needed by many libs / render fns
  117. $vnode: i => i.vnode,
  118. // inject additional properties into $options for compat
  119. // e.g. vuex needs this.$options.parent
  120. $options: i => {
  121. const res = extend({}, resolveMergedOptions(i))
  122. res.parent = i.proxy!.$parent
  123. res.propsData = i.vnode.props
  124. return res
  125. },
  126. // some private properties that are likely accessed...
  127. _self: i => i.proxy,
  128. _uid: i => i.uid,
  129. _data: i => i.data,
  130. _isMounted: i => i.isMounted,
  131. _isDestroyed: i => i.isUnmounted,
  132. // v2 render helpers
  133. $createElement: () => compatH,
  134. _c: () => compatH,
  135. _o: () => legacyMarkOnce,
  136. _n: () => looseToNumber,
  137. _s: () => toDisplayString,
  138. _l: () => renderList,
  139. _t: i => legacyRenderSlot.bind(null, i),
  140. _q: () => looseEqual,
  141. _i: () => looseIndexOf,
  142. _m: i => legacyRenderStatic.bind(null, i),
  143. _f: () => resolveFilter,
  144. _k: i => legacyCheckKeyCodes.bind(null, i),
  145. _b: () => legacyBindObjectProps,
  146. _v: () => createTextVNode,
  147. _e: () => createCommentVNode,
  148. _u: () => legacyresolveScopedSlots,
  149. _g: () => legacyBindObjectListeners,
  150. _d: () => legacyBindDynamicKeys,
  151. _p: () => legacyPrependModifier
  152. } as PublicPropertiesMap)
  153. }
  154. }