import Vue from 'vue' import { initHooks, initUnknownHooks, initMocks } from 'uni-wrapper/util' import { initAppLocale, normalizeLocale, LOCALE_EN } from 'uni-helpers/i18n/index' 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' ] function initEventChannel () { Vue.prototype.getOpenerEventChannel = function () { // 微信小程序使用自身getOpenerEventChannel if (__PLATFORM__ === 'mp-weixin') { return this.$scope.getOpenerEventChannel() } if (__PLATFORM__ === 'mp-alipay') { if (my.canIUse('getOpenerEventChannel')) { 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 = {} function currentId (fn) { const vueIds = this.$options.propsData.vueId if (vueIds) { const vueId = vueIds.split(',')[0] fn(vueId) } } Vue.prototype.$hasSSP = function (vueId) { const slot = center[vueId] if (!slot) { parents[vueId] = this this.$on('hook:destroyed', () => { delete parents[vueId] }) } return slot } Vue.prototype.$getSSP = function (vueId, name, needAll) { const slot = center[vueId] if (slot) { const params = slot[name] || [] if (needAll) { return params } return params[0] } } Vue.prototype.$setSSP = function (name, value) { let index = 0 currentId.call(this, vueId => { const slot = center[vueId] const params = slot[name] = slot[name] || [] params.push(value) index = params.length - 1 }) return index } Vue.prototype.$initSSP = function () { currentId.call(this, vueId => { center[vueId] = {} }) } Vue.prototype.$callSSP = function () { currentId.call(this, vueId => { 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() if (__PLATFORM__ === 'mp-weixin' || __PLATFORM__ === 'mp-qq' || __PLATFORM__ === 'mp-jd' || __PLATFORM__ === 'mp-xhs' || __PLATFORM__ === 'mp-toutiao' || __PLATFORM__ === 'mp-kuaishou' || __PLATFORM__ === 'mp-alipay' || __PLATFORM__ === 'mp-baidu' || __PLATFORM__ === 'mp-lark') { 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 ( (__PLATFORM__ === 'mp-toutiao' || __PLATFORM__ === 'mp-lark' ? this.mpType !== 'app' : 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] }) } initAppLocale(Vue, vm, normalizeLocale(__GLOBAL__.getSystemInfoSync().language) || LOCALE_EN) initHooks(appOptions, hooks) initUnknownHooks(appOptions, vm.$options) return appOptions }