component-parser.js 2.8 KB
Newer Older
fxy060608's avatar
fxy060608 已提交
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
import Vue from 'vue'

import {
  initData,
  initVueIds,
  handleEvent,
  initBehaviors,
  initProperties,
  initVueComponent
} from 'uni-wrapper/util'

import {
  handleRef,
  handleLink,
  initBehavior,
  initRelation,
  triggerEvent,
  createObserver,
  isComponent2,
  initChildVues
} from './util'

function initVm (VueComponent) {
  if (this.$vm) {
    return
  }
  const properties = this.props

  const options = {
    mpType: 'component',
    mpInstance: this,
    propsData: properties
  }

  initVueIds(properties.vueId, this)

  if (isComponent2) {
    // 处理父子关系
    initRelation.call(this, {
      vuePid: this._$vuePid,
      vueOptions: options
    })

    // 初始化 vue 实例
    this.$vm = new VueComponent(options)

    // 触发首次 setData
    this.$vm.$mount()
  } else {
    initChildVues(this)
    // 处理父子关系
    initRelation.call(this, {
      vuePid: this._$vuePid,
      vueOptions: options,
      VueComponent,
      mpInstance: this
    })
    if (options.parent) { // 父组件已经初始化,直接初始化子,否则放到父组件的 didMount 中处理
      // 初始化 vue 实例
      this.$vm = new VueComponent(options)
      handleRef.call(options.parent.$scope, this)
      // 触发首次 setData
      this.$vm.$mount()

      this.$vm._isMounted = true
      this.$vm.__call_hook('mounted')
      this.$vm.__call_hook('onReady')
    }
  }
}

export default function parseComponent (vueComponentOptions) {
  let [VueComponent, vueOptions] = initVueComponent(Vue, vueComponentOptions)

  const properties = initProperties(vueOptions.props, false, vueOptions.__file)

  const props = {
    onVueInit: function () {}
  }

  Object.keys(properties).forEach(key => {
    if (key !== 'vueSlots') {
      props[key] = properties[key].value
    }
  })

  const componentOptions = {
    mixins: initBehaviors(vueOptions, initBehavior),
    data: initData(vueOptions, Vue.prototype),
    props,
    didMount () {
      initVm.call(this, VueComponent)
      if (isComponent2) {
        this.$vm._isMounted = true
        this.$vm.__call_hook('mounted')
        this.$vm.__call_hook('onReady')
      }
    },
    didUnmount () {
      this.$vm.$destroy()
    },
    methods: {
      __r: handleRef,
      __e: handleEvent,
      __l: handleLink,
      triggerEvent
    }
  }

  if (isComponent2) {
    componentOptions.onInit = function onInit () {
      initVm.call(this, VueComponent)
    }
    componentOptions.deriveDataFromProps = createObserver()
  } else {
    componentOptions.didUpdate = createObserver(true)
  }

  if (vueOptions.methods && vueOptions.methods.formReset) {
    componentOptions.methods.formReset = vueOptions.methods.formReset
  }
  return componentOptions
}