保誠-保戶業務員媒合平台
Tomas
2022-05-19 957a1f10a06fdbb76f1a0ba94fe44126c613fee3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/* @flow */
 
// https://github.com/Hanks10100/weex-native-directive/tree/master/component
 
import { mergeOptions, isPlainObject, noop } from 'core/util/index'
import Watcher from 'core/observer/watcher'
import { initProxy } from 'core/instance/proxy'
import { initState, getData } from 'core/instance/state'
import { initRender } from 'core/instance/render'
import { initEvents } from 'core/instance/events'
import { initProvide, initInjections } from 'core/instance/inject'
import { initLifecycle, callHook } from 'core/instance/lifecycle'
import { initInternalComponent, resolveConstructorOptions } from 'core/instance/init'
import { registerComponentHook, updateComponentData } from '../../util/index'
 
let uid = 0
 
// override Vue.prototype._init
function initVirtualComponent (options: Object = {}) {
  const vm: Component = this
  const componentId = options.componentId
 
  // virtual component uid
  vm._uid = `virtual-component-${uid++}`
 
  // a flag to avoid this being observed
  vm._isVue = true
  // merge options
  if (options && options._isComponent) {
    // optimize internal component instantiation
    // since dynamic options merging is pretty slow, and none of the
    // internal component options needs special treatment.
    initInternalComponent(vm, options)
  } else {
    vm.$options = mergeOptions(
      resolveConstructorOptions(vm.constructor),
      options || {},
      vm
    )
  }
 
  /* istanbul ignore else */
  if (process.env.NODE_ENV !== 'production') {
    initProxy(vm)
  } else {
    vm._renderProxy = vm
  }
 
  vm._self = vm
  initLifecycle(vm)
  initEvents(vm)
  initRender(vm)
  callHook(vm, 'beforeCreate')
  initInjections(vm) // resolve injections before data/props
  initState(vm)
  initProvide(vm) // resolve provide after data/props
  callHook(vm, 'created')
 
  // send initial data to native
  const data = vm.$options.data
  const params = typeof data === 'function'
    ? getData(data, vm)
    : data || {}
  if (isPlainObject(params)) {
    updateComponentData(componentId, params)
  }
 
  registerComponentHook(componentId, 'lifecycle', 'attach', () => {
    callHook(vm, 'beforeMount')
 
    const updateComponent = () => {
      vm._update(vm._vnode, false)
    }
    new Watcher(vm, updateComponent, noop, null, true)
 
    vm._isMounted = true
    callHook(vm, 'mounted')
  })
 
  registerComponentHook(componentId, 'lifecycle', 'detach', () => {
    vm.$destroy()
  })
}
 
// override Vue.prototype._update
function updateVirtualComponent (vnode?: VNode) {
  const vm: Component = this
  const componentId = vm.$options.componentId
  if (vm._isMounted) {
    callHook(vm, 'beforeUpdate')
  }
  vm._vnode = vnode
  if (vm._isMounted && componentId) {
    // TODO: data should be filtered and without bindings
    const data = Object.assign({}, vm._data)
    updateComponentData(componentId, data, () => {
      callHook(vm, 'updated')
    })
  }
}
 
// listening on native callback
export function resolveVirtualComponent (vnode: MountedComponentVNode): VNode {
  const BaseCtor = vnode.componentOptions.Ctor
  const VirtualComponent = BaseCtor.extend({})
  const cid = VirtualComponent.cid
  VirtualComponent.prototype._init = initVirtualComponent
  VirtualComponent.prototype._update = updateVirtualComponent
 
  vnode.componentOptions.Ctor = BaseCtor.extend({
    beforeCreate () {
      // const vm: Component = this
 
      // TODO: listen on all events and dispatch them to the
      // corresponding virtual components according to the componentId.
      // vm._virtualComponents = {}
      const createVirtualComponent = (componentId, propsData) => {
        // create virtual component
        // const subVm =
        new VirtualComponent({
          componentId,
          propsData
        })
        // if (vm._virtualComponents) {
        //   vm._virtualComponents[componentId] = subVm
        // }
      }
 
      registerComponentHook(cid, 'lifecycle', 'create', createVirtualComponent)
    },
    beforeDestroy () {
      delete this._virtualComponents
    }
  })
}