component-base-parser.js 3.2 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
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
} = {}) {
fxy060608's avatar
fxy060608 已提交
22
  const [VueComponent, vueOptions] = initVueComponent(Vue, vueComponentOptions)
fxy060608's avatar
fxy060608 已提交
23

fxy060608's avatar
fxy060608 已提交
24 25
  const options = {
    multipleSlots: true,
J
jaceechan 已提交
26
    addGlobalClass: true,
27
    ...(vueOptions.options || {})
fxy060608's avatar
fxy060608 已提交
28 29
  }

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

fxy060608's avatar
fxy060608 已提交
37
  const componentOptions = {
fxy060608's avatar
fxy060608 已提交
38
    options,
fxy060608's avatar
fxy060608 已提交
39 40
    data: initData(vueOptions, Vue.prototype),
    behaviors: initBehaviors(vueOptions, initBehavior),
Q
qiang 已提交
41
    properties: initProperties(vueOptions.props, false, vueOptions.__file, options),
fxy060608's avatar
fxy060608 已提交
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
    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 已提交
77
          // this.is && console.warn(this.is + ' is not attached')
fxy060608's avatar
fxy060608 已提交
78 79 80
        }
      },
      detached () {
fxy060608's avatar
fxy060608 已提交
81
        this.$vm && this.$vm.$destroy()
fxy060608's avatar
fxy060608 已提交
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
      }
    },
    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
    }
  }
100 101 102 103
  // externalClasses
  if (vueOptions.externalClasses) {
    componentOptions.externalClasses = vueOptions.externalClasses
  }
fxy060608's avatar
fxy060608 已提交
104

fxy060608's avatar
fxy060608 已提交
105 106 107 108 109 110 111 112
  if (Array.isArray(vueOptions.wxsCallMethods)) {
    vueOptions.wxsCallMethods.forEach(callMethod => {
      componentOptions.methods[callMethod] = function (args) {
        return this.$vm[callMethod](args)
      }
    })
  }

fxy060608's avatar
fxy060608 已提交
113 114 115 116
  if (isPage) {
    return componentOptions
  }
  return [componentOptions, VueComponent]
J
jaceechan 已提交
117
}