create-component.js 2.4 KB
Newer Older
1 2 3 4
import Vue from 'vue'

import {
  handleLink,
fxy060608's avatar
fxy060608 已提交
5 6
  triggerLink,
  initComponent
7 8 9 10
} from 'uni-platform/runtime/wrapper/index'

import {
  getData,
11 12 13 14
  handleEvent,
  getProperties
} from './util'

fxy060608's avatar
fxy060608 已提交
15 16
function initVm (VueComponent) {
  if (this.$vm) {
fxy060608's avatar
fxy060608 已提交
17 18 19
    return
  }

fxy060608's avatar
fxy060608 已提交
20
  const options = {
fxy060608's avatar
fxy060608 已提交
21
    mpType: 'component',
fxy060608's avatar
fxy060608 已提交
22 23 24
    mpInstance: this,
    propsData: this.properties
  }
fxy060608's avatar
fxy060608 已提交
25
  // 初始化 vue 实例
fxy060608's avatar
fxy060608 已提交
26
  this.$vm = new VueComponent(options)
fxy060608's avatar
fxy060608 已提交
27

28
  // 处理$slots,$scopedSlots(暂不支持动态变化$slots)
fxy060608's avatar
fxy060608 已提交
29
  const vueSlots = this.properties.vueSlots
30 31 32 33 34
  if (Array.isArray(vueSlots) && vueSlots.length) {
    const $slots = Object.create(null)
    vueSlots.forEach(slotName => {
      $slots[slotName] = true
    })
fxy060608's avatar
fxy060608 已提交
35
    this.$vm.$scopedSlots = this.$vm.$slots = $slots
36
  }
fxy060608's avatar
fxy060608 已提交
37 38
  // 性能优先,mount 提前到 attached 中,保证组件首次渲染数据被合并
  // 导致与标准 Vue 的差异,data 和 computed 中不能使用$parent,provide等组件属性
fxy060608's avatar
fxy060608 已提交
39
  this.$vm.$mount()
fxy060608's avatar
fxy060608 已提交
40 41
}

42 43 44 45 46 47 48 49 50 51 52 53
export function createComponent (vueOptions) {
  vueOptions = vueOptions.default || vueOptions

  const properties = getProperties(vueOptions.props)

  const VueComponent = Vue.extend(vueOptions)

  const componentOptions = {
    options: {
      multipleSlots: true,
      addGlobalClass: true
    },
fxy060608's avatar
fxy060608 已提交
54
    data: getData(vueOptions, Vue.prototype),
55
    properties,
fxy060608's avatar
fxy060608 已提交
56 57
    lifetimes: {
      attached () {
fxy060608's avatar
fxy060608 已提交
58
        initVm.call(this, VueComponent)
fxy060608's avatar
fxy060608 已提交
59 60
      },
      ready () {
fxy060608's avatar
fxy060608 已提交
61
        initVm.call(this, VueComponent) // 目前发现部分情况小程序 attached 不触发
62
        triggerLink(this) // 处理 parent,children
63

fxy060608's avatar
fxy060608 已提交
64
        // 补充生命周期
65
        this.$vm.__call_hook('created')
fxy060608's avatar
fxy060608 已提交
66
        this.$vm.__call_hook('beforeMount')
fxy060608's avatar
fxy060608 已提交
67 68 69 70 71 72 73
        this.$vm._isMounted = true
        this.$vm.__call_hook('mounted')
        this.$vm.__call_hook('onReady')
      },
      detached () {
        this.$vm.$destroy()
      }
74 75 76 77 78 79
    },
    pageLifetimes: {
      show (args) {
        this.$vm.__call_hook('onPageShow', args)
      },
      hide () {
80
        this.$vm && this.$vm.__call_hook('onPageHide')
81 82
      },
      resize (size) {
83
        this.$vm && this.$vm.__call_hook('onPageResize', size)
84 85 86 87 88 89 90 91
      }
    },
    methods: {
      __e: handleEvent,
      __l: handleLink
    }
  }

fxy060608's avatar
fxy060608 已提交
92 93
  initComponent(componentOptions)

94 95
  return Component(componentOptions)
}