app-base-parser.js 4.7 KB
Newer Older
1 2 3 4 5 6 7
import Vue from 'vue'

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

8 9 10 11
import {
  initAppLocale
} from 'uni-helpers/i18n/index'

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
import EventChannel from 'uni-helpers/EventChannel'

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

import {
  uniIdMixin
} from 'uni-shared'

const hooks = [
  'onShow',
  'onHide',
  'onError',
  'onPageNotFound',
  'onThemeChange',
  'onUnhandledRejection'
]

if (__PLATFORM__ === 'mp-alipay') {
  hooks.push('onShareAppMessage')
}

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)
  }
}

function initScopedSlotsParams () {
  const center = {}
  const parents = {}

  Vue.prototype.$hasScopedSlotsParams = function (vueId) {
    const has = center[vueId]
    if (!has) {
      parents[vueId] = this
Q
qiang 已提交
64
      this.$on('hook:destroyed', () => {
65 66 67 68 69 70 71 72 73 74 75 76 77
        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
Q
qiang 已提交
78
      this.$on('hook:destroyed', () => {
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
        delete parents[vueId]
      })
    }
  }

  Vue.prototype.$setScopedSlotsParams = function (name, value) {
    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()
      }
    }
  }

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

export default function parseBaseApp (vm, {
  mocks,
  initRefs
}) {
  initEventChannel()
石小磊 已提交
113
  if (__PLATFORM__ === 'mp-weixin' || __PLATFORM__ === 'mp-qq'|| __PLATFORM__ === 'mp-jd' || __PLATFORM__ === 'mp-toutiao' || __PLATFORM__ ===
P
panyiming.325 已提交
114
    'mp-kuaishou' || __PLATFORM__ === 'mp-alipay' || __PLATFORM__ === 'mp-baidu' || __PLATFORM__ === 'mp-lark') {
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
    initScopedSlotsParams()
  }
  if (vm.$options.store) {
    Vue.prototype.$store = vm.$options.store
  }
  uniIdMixin(Vue)

  Vue.prototype.mpHost = __PLATFORM__

  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
      if (this.mpType === 'page' && typeof getApp === 'function') { // hack vue-i18n
        const app = getApp()
        if (app.$vm && app.$vm.$i18n) {
          this._i18n = app.$vm.$i18n
        }
      }
      if (this.mpType !== 'app') {
        initRefs(this)
        initMocks(this, mocks)
      }
    }
  })

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

      this.$vm = vm

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

      this.$vm.$scope = this
      // vm 上也挂载 globalData
      this.$vm.globalData = this.globalData

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

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

  // 兼容旧版本 globalData
  appOptions.globalData = vm.$options.globalData || {}
  // 将 methods 中的方法挂在 getApp() 中
  const methods = vm.$options.methods
  if (methods) {
    Object.keys(methods).forEach(name => {
      appOptions[name] = methods[name]
    })
  }

192 193
  initAppLocale(Vue, vm, __GLOBAL__.getSystemInfoSync().language || 'zh-Hans')

194 195 196
  initHooks(appOptions, hooks)

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