create-component.js 2.9 KB
Newer Older
1 2 3 4 5 6 7 8 9
import Vue from 'vue'

import {
  getData,
  handleLink,
  handleEvent,
  getProperties
} from './util'

fxy060608's avatar
fxy060608 已提交
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
function initVueComponent (mpInstace, VueComponent) {
  if (mpInstace.$vm) {
    return
  }

  const options = {
    mpType: 'component',
    mpInstance: mpInstace,
    propsData: mpInstace.properties
  }
  // 初始化 vue 实例
  mpInstace.$vm = new VueComponent(options)

  // 初始化渲染数据
  mpInstace.$vm.$mount()
}

27 28 29 30 31 32 33 34 35 36 37 38
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 已提交
39
    data: getData(vueOptions),
40
    properties,
fxy060608's avatar
fxy060608 已提交
41 42 43 44 45 46
    lifetimes: {
      attached () {
        initVueComponent(this, VueComponent)
      },
      ready () {
        initVueComponent(this, VueComponent) // 目前发现部分情况小程序 attached 不触发
47

fxy060608's avatar
fxy060608 已提交
48 49
        if (__PLATFORM__ === 'mp-baidu') {
          const baiduComponentInstances = this.pageinstance.$baiduComponentInstances
50

fxy060608's avatar
fxy060608 已提交
51 52 53 54 55 56 57 58 59 60 61 62 63 64
          baiduComponentInstances[this.id] = this
          if (this.ownerId) { // 组件嵌组件
            const parentBaiduComponentInstance = baiduComponentInstances[this.ownerId]
            if (parentBaiduComponentInstance) {
              this.$vm.$parent = parentBaiduComponentInstance.$vm
            } else {
              console.error(`查找父组件失败${this.ownerId}`)
            }
          } else { // 页面直属组件
            this.$vm.$parent = this.pageinstance.$vm
          }
        } else {
          this.triggerEvent('__l', this.$vm) // TODO 百度仅能传递 json 对象
        }
65

fxy060608's avatar
fxy060608 已提交
66 67 68 69 70 71 72 73 74
        const eventId = this.dataset.eventId
        if (eventId) {
          const listeners = this.$vm.$parent.$mp.listeners
          if (listeners) {
            const listenerOpts = listeners[eventId]
            Object.keys(listenerOpts).forEach(eventType => {
              listenerOpts[eventType].forEach(handler => {
                this.$vm[handler.once ? '$once' : '$on'](eventType, handler)
              })
75
            })
fxy060608's avatar
fxy060608 已提交
76
          }
77
        }
78

fxy060608's avatar
fxy060608 已提交
79 80 81 82 83 84 85 86 87 88
        this.$vm._isMounted = true
        this.$vm.__call_hook('mounted')
        this.$vm.__call_hook('onReady')
      },
      detached () {
        if (__PLATFORM__ === 'mp-baidu') {
          delete this.pageinstance.$baiduComponentInstances[this.id]
        }
        this.$vm.$destroy()
      }
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
    },
    pageLifetimes: {
      show (args) {
        this.$vm.__call_hook('onPageShow', args)
      },
      hide () {
        this.$vm.__call_hook('onPageHide')
      },
      resize (size) {
        this.$vm.__call_hook('onPageResize', size)
      }
    },
    methods: {
      __e: handleEvent,
      __l: handleLink
    }
  }

  return Component(componentOptions)
}