app-base-parser.js 4.8 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
import {
  initAppLocale
} from 'uni-helpers/i18n/index'

fxy060608's avatar
fxy060608 已提交
12 13 14 15 16 17
import EventChannel from 'uni-helpers/EventChannel'

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

雪洛's avatar
雪洛 已提交
18 19 20 21
import {
  uniIdMixin
} from 'uni-shared'

fxy060608's avatar
fxy060608 已提交
22
const hooks = [
fxy060608's avatar
fxy060608 已提交
23
  'onShow',
fxy060608's avatar
fxy060608 已提交
24 25
  'onHide',
  'onError',
fxy060608's avatar
fxy060608 已提交
26 27
  'onPageNotFound',
  'onThemeChange',
28
  'onUnhandledRejection'
fxy060608's avatar
fxy060608 已提交
29 30
]

fxy060608's avatar
fxy060608 已提交
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
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)
  }
}

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
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) {
81 82 83 84 85 86 87 88
    const vueIds = this.$options.propsData.vueId
    if (vueIds) {
      const vueId = vueIds.split(',')[0]
      const object = center[vueId] = center[vueId] || {}
      object[name] = value
      if (parents[vueId]) {
        parents[vueId].$forceUpdate()
      }
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
    }
  }

  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 已提交
104
export default function parseBaseApp (vm, {
fxy060608's avatar
fxy060608 已提交
105 106
  mocks,
  initRefs
fxy060608's avatar
fxy060608 已提交
107
}) {
fxy060608's avatar
fxy060608 已提交
108
  initEventChannel()
fxy060608's avatar
fxy060608 已提交
109 110
  if (__PLATFORM__ === 'mp-weixin' || __PLATFORM__ === 'mp-qq' || __PLATFORM__ === 'mp-toutiao' || __PLATFORM__ ===
    'mp-kuaishou' || __PLATFORM__ === 'mp-alipay' || __PLATFORM__ === 'mp-baidu') {
111 112
    initScopedSlotsParams()
  }
fxy060608's avatar
fxy060608 已提交
113 114 115
  if (vm.$options.store) {
    Vue.prototype.$store = vm.$options.store
  }
雪洛's avatar
雪洛 已提交
116
  uniIdMixin(Vue)
fxy060608's avatar
fxy060608 已提交
117

fxy060608's avatar
fxy060608 已提交
118
  Vue.prototype.mpHost = __PLATFORM__
fxy060608's avatar
fxy060608 已提交
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136

  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
137
      if (this.mpType === 'page' && typeof getApp === 'function') { // hack vue-i18n
fxy060608's avatar
fxy060608 已提交
138 139 140 141 142
        const app = getApp()
        if (app.$vm && app.$vm.$i18n) {
          this._i18n = app.$vm.$i18n
        }
      }
fxy060608's avatar
fxy060608 已提交
143 144 145 146 147 148 149 150 151
      if (this.mpType !== 'app') {
        initRefs(this)
        initMocks(this, mocks)
      }
    }
  })

  const appOptions = {
    onLaunch (args) {
fxy060608's avatar
fxy060608 已提交
152 153 154
      if (this.$vm) { // 已经初始化过了,主要是为了百度,百度 onShow 在 onLaunch 之前
        return
      }
fxy060608's avatar
fxy060608 已提交
155
      if (__PLATFORM__ === 'mp-weixin' || __PLATFORM__ === 'mp-qq') {
156
        if (wx.canIUse && !wx.canIUse('nextTick')) { // 事实 上2.2.3 即可,简单使用 2.3.0 的 nextTick 判断
fxy060608's avatar
fxy060608 已提交
157 158 159 160 161 162 163 164 165 166
          console.error('当前微信基础库版本过低,请将 微信开发者工具-详情-项目设置-调试基础库版本 更换为`2.3.0`以上')
        }
      }

      this.$vm = vm

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

fxy060608's avatar
fxy060608 已提交
167 168
      this.$vm.$scope = this
      // vm 上也挂载 globalData
fxy060608's avatar
fxy060608 已提交
169
      this.$vm.globalData = this.globalData
fxy060608's avatar
fxy060608 已提交
170 171 172 173 174 175 176 177 178 179

      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 已提交
180 181 182 183 184 185 186
  // 将 methods 中的方法挂在 getApp() 中
  const methods = vm.$options.methods
  if (methods) {
    Object.keys(methods).forEach(name => {
      appOptions[name] = methods[name]
    })
  }
fxy060608's avatar
fxy060608 已提交
187

fxy060608's avatar
fxy060608 已提交
188 189
  initAppLocale(Vue, vm, __GLOBAL__.getSystemInfoSync().language || 'zh-Hans')

fxy060608's avatar
fxy060608 已提交
190 191 192
  initHooks(appOptions, hooks)

  return appOptions
fxy060608's avatar
fxy060608 已提交
193
}