component-base-parser.js 3.0 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
import Vue from 'vue'

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

import {
  handleLink,
  initBehavior
} from './util'

export default function parseBaseComponent (vueComponentOptions, {
  isPage,
  initRelation
} = {}) {
  let [VueComponent, vueOptions] = initVueComponent(Vue, vueComponentOptions)

fxy060608's avatar
fxy060608 已提交
24 25 26 27 28
  const options = {
    multipleSlots: true,
    addGlobalClass: true
  }

fxy060608's avatar
fxy060608 已提交
29 30
  if (__PLATFORM__ === 'mp-weixin' || __PLATFORM__ === 'mp-qq') {
    // 微信 multipleSlots 部分情况有 bug,导致内容顺序错乱 如 u-list,提供覆盖选项
fxy060608's avatar
fxy060608 已提交
31 32
    if (vueOptions['mp-weixin'] && vueOptions['mp-weixin']['options']) {
      Object.assign(options, vueOptions['mp-weixin']['options'])
fxy060608's avatar
fxy060608 已提交
33 34 35
    }
  }

fxy060608's avatar
fxy060608 已提交
36
  const componentOptions = {
fxy060608's avatar
fxy060608 已提交
37
    options,
fxy060608's avatar
fxy060608 已提交
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
    data: initData(vueOptions, Vue.prototype),
    behaviors: initBehaviors(vueOptions, initBehavior),
    properties: initProperties(vueOptions.props, false, vueOptions.__file),
    lifetimes: {
      attached () {
        const properties = this.properties

        const options = {
          mpType: isPage.call(this) ? 'page' : 'component',
          mpInstance: this,
          propsData: properties
        }

        initVueIds(properties.vueId, this)

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

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

        // 处理$slots,$scopedSlots(暂不支持动态变化$slots)
        initSlots(this.$vm, properties.vueSlots)

        // 触发首次 setData
        this.$vm.$mount()
      },
      ready () {
        // 当组件 props 默认值为 true,初始化时传入 false 会导致 created,ready 触发, 但 attached 不触发
        // https://developers.weixin.qq.com/community/develop/doc/00066ae2844cc0f8eb883e2a557800
        if (this.$vm) {
          this.$vm._isMounted = true
          this.$vm.__call_hook('mounted')
          this.$vm.__call_hook('onReady')
        } else {
fxy060608's avatar
fxy060608 已提交
76
          // this.is && console.warn(this.is + ' is not attached')
fxy060608's avatar
fxy060608 已提交
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
        }
      },
      detached () {
        this.$vm.$destroy()
      }
    },
    pageLifetimes: {
      show (args) {
        this.$vm && this.$vm.__call_hook('onPageShow', args)
      },
      hide () {
        this.$vm && this.$vm.__call_hook('onPageHide')
      },
      resize (size) {
        this.$vm && this.$vm.__call_hook('onPageResize', size)
      }
    },
    methods: {
      __l: handleLink,
      __e: handleEvent
    }
  }

fxy060608's avatar
fxy060608 已提交
100 101 102 103 104 105 106 107
  if (Array.isArray(vueOptions.wxsCallMethods)) {
    vueOptions.wxsCallMethods.forEach(callMethod => {
      componentOptions.methods[callMethod] = function (args) {
        return this.$vm[callMethod](args)
      }
    })
  }

fxy060608's avatar
fxy060608 已提交
108 109 110 111 112
  if (isPage) {
    return componentOptions
  }
  return [componentOptions, VueComponent]
}