app-base-parser.js 4.3 KB
Newer Older
fxy060608's avatar
fxy060608 已提交
1 2 3 4 5 6 7
import Vue from 'vue'

import {
  initHooks,
  initMocks
} from 'uni-wrapper/util'

fxy060608's avatar
fxy060608 已提交
8 9 10 11 12 13
import EventChannel from 'uni-helpers/EventChannel'

import {
  getEventChannel
} from 'uni-helpers/navigate-to'

fxy060608's avatar
fxy060608 已提交
14
const hooks = [
fxy060608's avatar
fxy060608 已提交
15
  'onShow',
fxy060608's avatar
fxy060608 已提交
16 17
  'onHide',
  'onError',
fxy060608's avatar
fxy060608 已提交
18 19
  'onPageNotFound',
  'onThemeChange',
20
  'onUnhandledRejection'
fxy060608's avatar
fxy060608 已提交
21 22
]

fxy060608's avatar
fxy060608 已提交
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
function initEventChannel () {
  Vue.prototype.getOpenerEventChannel = function () {
    // 微信小程序使用自身getOpenerEventChannel
    if (__PLATFORM__ === 'mp-weixin') {
      return this.$scope.getOpenerEventChannel()
    }
    if (!this.__eventChannel__) {
      this.__eventChannel__ = new EventChannel()
    }
    return this.__eventChannel__
  }
  const callHook = Vue.prototype.__call_hook
  Vue.prototype.__call_hook = function (hook, args) {
    if (hook === 'onLoad' && args && args.__id__) {
      this.__eventChannel__ = getEventChannel(args.__id__)
      delete args.__id__
    }
    return callHook.call(this, hook, args)
  }
}

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
function initScopedSlotsParams () {
  const center = {}
  const parents = {}

  Vue.prototype.$hasScopedSlotsParams = function (vueId) {
    const has = center[vueId]
    if (!has) {
      parents[vueId] = this
      this.$on('hook:destory', () => {
        delete parents[vueId]
      })
    }
    return has
  }

  Vue.prototype.$getScopedSlotsParams = function (vueId, name, key) {
    const data = center[vueId]
    if (data) {
      const object = data[name] || {}
      return key ? object[key] : object
    } else {
      parents[vueId] = this
      this.$on('hook:destory', () => {
        delete parents[vueId]
      })
    }
  }

  Vue.prototype.$setScopedSlotsParams = function (name, value) {
    const vueId = this.$options.propsData.vueId
    const object = center[vueId] = center[vueId] || {}
    object[name] = value
    if (parents[vueId]) {
      parents[vueId].$forceUpdate()
    }
  }

  Vue.mixin({
    destroyed () {
      const propsData = this.$options.propsData
      const vueId = propsData && propsData.vueId
      if (vueId) {
        delete center[vueId]
        delete parents[vueId]
      }
    }
  })
}

fxy060608's avatar
fxy060608 已提交
93
export default function parseBaseApp (vm, {
fxy060608's avatar
fxy060608 已提交
94 95
  mocks,
  initRefs
fxy060608's avatar
fxy060608 已提交
96
}) {
fxy060608's avatar
fxy060608 已提交
97
  initEventChannel()
98
  initScopedSlotsParams()
fxy060608's avatar
fxy060608 已提交
99 100 101
  if (vm.$options.store) {
    Vue.prototype.$store = vm.$options.store
  }
fxy060608's avatar
fxy060608 已提交
102

fxy060608's avatar
fxy060608 已提交
103
  Vue.prototype.mpHost = __PLATFORM__
fxy060608's avatar
fxy060608 已提交
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121

  Vue.mixin({
    beforeCreate () {
      if (!this.$options.mpType) {
        return
      }

      this.mpType = this.$options.mpType

      this.$mp = {
        data: {},
        [this.mpType]: this.$options.mpInstance
      }

      this.$scope = this.$options.mpInstance

      delete this.$options.mpType
      delete this.$options.mpInstance
122
      if (this.mpType === 'page' && typeof getApp === 'function') { // hack vue-i18n
fxy060608's avatar
fxy060608 已提交
123 124 125 126 127
        const app = getApp()
        if (app.$vm && app.$vm.$i18n) {
          this._i18n = app.$vm.$i18n
        }
      }
fxy060608's avatar
fxy060608 已提交
128 129 130 131 132 133 134 135 136
      if (this.mpType !== 'app') {
        initRefs(this)
        initMocks(this, mocks)
      }
    }
  })

  const appOptions = {
    onLaunch (args) {
fxy060608's avatar
fxy060608 已提交
137 138 139
      if (this.$vm) { // 已经初始化过了,主要是为了百度,百度 onShow 在 onLaunch 之前
        return
      }
fxy060608's avatar
fxy060608 已提交
140
      if (__PLATFORM__ === 'mp-weixin' || __PLATFORM__ === 'mp-qq') {
141
        if (wx.canIUse && !wx.canIUse('nextTick')) { // 事实 上2.2.3 即可,简单使用 2.3.0 的 nextTick 判断
fxy060608's avatar
fxy060608 已提交
142 143 144 145 146 147 148 149 150 151
          console.error('当前微信基础库版本过低,请将 微信开发者工具-详情-项目设置-调试基础库版本 更换为`2.3.0`以上')
        }
      }

      this.$vm = vm

      this.$vm.$mp = {
        app: this
      }

fxy060608's avatar
fxy060608 已提交
152 153
      this.$vm.$scope = this
      // vm 上也挂载 globalData
fxy060608's avatar
fxy060608 已提交
154
      this.$vm.globalData = this.globalData
fxy060608's avatar
fxy060608 已提交
155 156 157 158 159 160 161 162 163 164

      this.$vm._isMounted = true
      this.$vm.__call_hook('mounted', args)

      this.$vm.__call_hook('onLaunch', args)
    }
  }

  // 兼容旧版本 globalData
  appOptions.globalData = vm.$options.globalData || {}
fxy060608's avatar
fxy060608 已提交
165 166 167 168 169 170 171
  // 将 methods 中的方法挂在 getApp() 中
  const methods = vm.$options.methods
  if (methods) {
    Object.keys(methods).forEach(name => {
      appOptions[name] = methods[name]
    })
  }
fxy060608's avatar
fxy060608 已提交
172 173 174 175

  initHooks(appOptions, hooks)

  return appOptions
176
}