import { SLOT_DEFAULT_NAME, EventChannel, invokeArrayFns, ON_LOAD, ON_SHOW, ON_HIDE, ON_UNLOAD, ON_RESIZE, ON_TAB_ITEM_TAP, ON_REACH_BOTTOM, ON_PULL_DOWN_REFRESH, ON_ADD_TO_FAVORITES, MINI_PROGRAM_PAGE_RUNTIME_HOOKS, isUniLifecycleHook, ON_READY, once, ON_LAUNCH, ON_ERROR, ON_THEME_CHANGE, ON_PAGE_NOT_FOUND, ON_UNHANDLE_REJECTION, addLeadingSlash, stringifyQuery, ON_INIT, customizeEvent } from '@dcloudio/uni-shared'; import { isArray, hasOwn, isFunction, extend, hyphenate, isPlainObject } from '@vue/shared'; import { ref, nextTick, findComponentPropsData, toRaw, updateProps, hasQueueJob, invalidateJob, getExposeProxy, pruneComponentPropsCache } from 'vue'; import { normalizeLocale, LOCALE_EN } from '@dcloudio/uni-i18n'; const MP_METHODS = [ 'createSelectorQuery', 'createIntersectionObserver', 'selectAllComponents', 'selectComponent', ]; function createEmitFn(oldEmit, ctx) { return function emit(event, ...args) { const scope = ctx.$scope; if (scope && event) { const detail = { __args__: args }; // 百度小程序,快手小程序,自定义组件不能绑定动态事件 { detail.__ins__ = scope; } { scope.triggerEvent(event, detail); } } return oldEmit.apply(this, [event, ...args]); }; } function initBaseInstance(instance, options) { const ctx = instance.ctx; // mp ctx.mpType = options.mpType; // @deprecated ctx.$mpType = options.mpType; ctx.$mpPlatform = "mp-baidu"; ctx.$scope = options.mpInstance; // TODO @deprecated ctx.$mp = {}; if (__VUE_OPTIONS_API__) { ctx._self = {}; } // slots instance.slots = {}; if (isArray(options.slots) && options.slots.length) { options.slots.forEach((name) => { instance.slots[name] = true; }); if (instance.slots[SLOT_DEFAULT_NAME]) { instance.slots.default = true; } } ctx.getOpenerEventChannel = function () { if (!this.__eventChannel__) { this.__eventChannel__ = new EventChannel(); } return this.__eventChannel__; }; ctx.$hasHook = hasHook; ctx.$callHook = callHook; // $emit instance.emit = createEmitFn(instance.emit, ctx); } function initComponentInstance(instance, options) { initBaseInstance(instance, options); const ctx = instance.ctx; MP_METHODS.forEach((method) => { ctx[method] = function (...args) { const mpInstance = ctx.$scope; if (mpInstance && mpInstance[method]) { return mpInstance[method].apply(mpInstance, args); } }; }); } function initMocks(instance, mpInstance, mocks) { const ctx = instance.ctx; mocks.forEach((mock) => { if (hasOwn(mpInstance, mock)) { instance[mock] = ctx[mock] = mpInstance[mock]; } }); } function hasHook(name) { const hooks = this.$[name]; if (hooks && hooks.length) { return true; } return false; } function callHook(name, args) { if (name === 'mounted') { callHook.call(this, 'bm'); // beforeMount this.$.isMounted = true; name = 'm'; } { if (name === 'onLoad' && args && args.__id__) { this.__eventChannel__ = swan.getEventChannel(args.__id__); delete args.__id__; } } const hooks = this.$[name]; return hooks && invokeArrayFns(hooks, args); } const PAGE_INIT_HOOKS = [ ON_LOAD, ON_SHOW, ON_HIDE, ON_UNLOAD, ON_RESIZE, ON_TAB_ITEM_TAP, ON_REACH_BOTTOM, ON_PULL_DOWN_REFRESH, ON_ADD_TO_FAVORITES, // 'onReady', // lifetimes.ready // 'onPageScroll', // 影响性能,开发者手动注册 // 'onShareTimeline', // 右上角菜单,开发者手动注册 // 'onShareAppMessage' // 右上角菜单,开发者手动注册 ]; function findHooks(vueOptions, hooks = new Set()) { if (vueOptions) { Object.keys(vueOptions).forEach((name) => { if (isUniLifecycleHook(name, vueOptions[name])) { hooks.add(name); } }); if (__VUE_OPTIONS_API__) { const { extends: extendsOptions, mixins } = vueOptions; if (mixins) { mixins.forEach((mixin) => findHooks(mixin, hooks)); } if (extendsOptions) { findHooks(extendsOptions, hooks); } } } return hooks; } function initHook(mpOptions, hook, excludes) { if (excludes.indexOf(hook) === -1 && !hasOwn(mpOptions, hook)) { mpOptions[hook] = function (args) { return this.$vm && this.$vm.$callHook(hook, args); }; } } const EXCLUDE_HOOKS = [ON_READY]; function initHooks(mpOptions, hooks, excludes = EXCLUDE_HOOKS) { hooks.forEach((hook) => initHook(mpOptions, hook, excludes)); } function initUnknownHooks(mpOptions, vueOptions, excludes = EXCLUDE_HOOKS) { findHooks(vueOptions).forEach((hook) => initHook(mpOptions, hook, excludes)); } function initRuntimeHooks(mpOptions, runtimeHooks) { if (!runtimeHooks) { return; } const hooks = Object.keys(MINI_PROGRAM_PAGE_RUNTIME_HOOKS); hooks.forEach((hook) => { if (runtimeHooks & MINI_PROGRAM_PAGE_RUNTIME_HOOKS[hook]) { initHook(mpOptions, hook, []); } }); } const findMixinRuntimeHooks = /*#__PURE__*/ once(() => { const runtimeHooks = []; const app = getApp({ allowDefault: true }); if (app && app.$vm && app.$vm.$) { const mixins = app.$vm.$.appContext.mixins; if (isArray(mixins)) { const hooks = Object.keys(MINI_PROGRAM_PAGE_RUNTIME_HOOKS); mixins.forEach((mixin) => { hooks.forEach((hook) => { if (hasOwn(mixin, hook) && !runtimeHooks.includes(hook)) { runtimeHooks.push(hook); } }); }); } } return runtimeHooks; }); function initMixinRuntimeHooks(mpOptions) { initHooks(mpOptions, findMixinRuntimeHooks()); } const HOOKS = [ ON_SHOW, ON_HIDE, ON_ERROR, ON_THEME_CHANGE, ON_PAGE_NOT_FOUND, ON_UNHANDLE_REJECTION, ]; function parseApp(instance, parseAppOptions) { const internalInstance = instance.$; const appOptions = { globalData: (instance.$options && instance.$options.globalData) || {}, $vm: instance, onLaunch(options) { this.$vm = instance; // 飞书小程序可能会把 AppOptions 序列化,导致 $vm 对象部分属性丢失 const ctx = internalInstance.ctx; if (this.$vm && ctx.$scope) { // 已经初始化过了,主要是为了百度,百度 onShow 在 onLaunch 之前 return; } initBaseInstance(internalInstance, { mpType: 'app', mpInstance: this, slots: [], }); ctx.globalData = this.globalData; instance.$callHook(ON_LAUNCH, options); }, }; initLocale(instance); const vueOptions = instance.$.type; initHooks(appOptions, HOOKS); initUnknownHooks(appOptions, vueOptions); if (__VUE_OPTIONS_API__) { const methods = vueOptions.methods; methods && extend(appOptions, methods); } if (parseAppOptions) { parseAppOptions.parse(appOptions); } return appOptions; } function initCreateApp(parseAppOptions) { return function createApp(vm) { return App(parseApp(vm, parseAppOptions)); }; } function initCreateSubpackageApp(parseAppOptions) { return function createApp(vm) { const appOptions = parseApp(vm, parseAppOptions); const app = getApp({ allowDefault: true, }); vm.$.ctx.$scope = app; const globalData = app.globalData; if (globalData) { Object.keys(appOptions.globalData).forEach((name) => { if (!hasOwn(globalData, name)) { globalData[name] = appOptions.globalData[name]; } }); } Object.keys(appOptions).forEach((name) => { if (!hasOwn(app, name)) { app[name] = appOptions[name]; } }); initAppLifecycle(appOptions, vm); if (process.env.UNI_SUBPACKAGE) { (swan.$subpackages || (swan.$subpackages = {}))[process.env.UNI_SUBPACKAGE] = { $vm: vm, }; } }; } function initAppLifecycle(appOptions, vm) { if (isFunction(appOptions.onLaunch)) { const args = swan.getLaunchOptionsSync && swan.getLaunchOptionsSync(); appOptions.onLaunch(args); } if (isFunction(appOptions.onShow) && swan.onAppShow) { swan.onAppShow((args) => { vm.$callHook('onShow', args); }); } if (isFunction(appOptions.onHide) && swan.onAppHide) { swan.onAppHide((args) => { vm.$callHook('onHide', args); }); } } function initLocale(appVm) { const locale = ref(normalizeLocale(swan.getSystemInfoSync().language) || LOCALE_EN); Object.defineProperty(appVm, '$locale', { get() { return locale.value; }, set(v) { locale.value = v; }, }); } function initVueIds(vueIds, mpInstance) { if (!vueIds) { return; } const ids = vueIds.split(','); const len = ids.length; if (len === 1) { mpInstance._$vueId = ids[0]; } else if (len === 2) { mpInstance._$vueId = ids[0]; mpInstance._$vuePid = ids[1]; } } const EXTRAS = ['externalClasses']; function initExtraOptions(miniProgramComponentOptions, vueOptions) { EXTRAS.forEach((name) => { if (hasOwn(vueOptions, name)) { miniProgramComponentOptions[name] = vueOptions[name]; } }); } function initWxsCallMethods(methods, wxsCallMethods) { if (!isArray(wxsCallMethods)) { return; } wxsCallMethods.forEach((callMethod) => { methods[callMethod] = function (args) { return this.$vm[callMethod](args); }; }); } function selectAllComponents(mpInstance, selector, $refs) { const components = mpInstance.selectAllComponents(selector); components.forEach((component) => { const ref = component.properties.uR; $refs[ref] = component.$vm || component; }); } function initRefs(instance, mpInstance) { Object.defineProperty(instance, 'refs', { get() { const $refs = {}; selectAllComponents(mpInstance, '.r', $refs); const forComponents = mpInstance.selectAllComponents('.r-i-f'); forComponents.forEach((component) => { const ref = component.properties.uR; if (!ref) { return; } if (!$refs[ref]) { $refs[ref] = []; } $refs[ref].push(component.$vm || component); }); return $refs; }, }); } function findVmByVueId(instance, vuePid) { // 标准 vue3 中 没有 $children,定制了内核 const $children = instance.$children; // 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200) for (let i = $children.length - 1; i >= 0; i--) { const childVm = $children[i]; if (childVm.$scope._$vueId === vuePid) { return childVm; } } // 反向递归查找 let parentVm; for (let i = $children.length - 1; i >= 0; i--) { parentVm = findVmByVueId($children[i], vuePid); if (parentVm) { return parentVm; } } } const EVENT_OPTS = 'eO'; /** * 需要搭配: * ./componentInstance/index.ts:24 triggerEvent 时传递 __ins__ * ./componentProps.ts:49 增加 properties eO * @param this * @param event * @returns */ function handleEvent(event) { const { type, target: { dataset }, detail: { __ins__ }, } = event; let methodName = type; // 快手小程序的 __l 方法也会走此处逻辑,但没有 __ins__ if (__ins__) { // 自定义事件,通过 triggerEvent 传递 __ins__ let eventObj = {}; try { // https://github.com/dcloudio/uni-app/issues/3647 // 通过字符串序列化解决百度小程序修改对象不触发组件properties变化的Bug eventObj = JSON.parse(__ins__.properties[EVENT_OPTS]); } catch (e) { } methodName = resolveMethodName(type, eventObj); } else if (dataset && dataset[EVENT_OPTS]) { // 快手小程序 input 等内置组件的 input 事件也会走此逻辑,所以从 dataset 中读取 methodName = resolveMethodName(type, dataset[EVENT_OPTS]); } if (!this[methodName]) { return console.warn(type + ' not found'); } this[methodName](event); } function resolveMethodName(name, obj) { return obj[name] || obj[hyphenate(name)]; } function nextSetDataTick(mpInstance, fn) { // 随便设置一个字段来触发回调(部分平台必须有字段才可以,比如头条) mpInstance.setData({ r1: 1 }, () => fn()); } function initSetRef(mpInstance) { if (!mpInstance._$setRef) { mpInstance._$setRef = (fn) => { nextTick(() => nextSetDataTick(mpInstance, fn)); }; } } const builtInProps = [ // 百度小程序,快手小程序自定义组件不支持绑定动态事件,动态dataset,故通过props传递事件信息 // event-opts 'eO', // 组件 ref 'uR', // 组件 ref-in-for 'uRIF', // 组件 id 'uI', // 组件类型 m: 小程序组件 'uT', // 组件 props 'uP', // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots 'uS', ]; function initDefaultProps(options, isBehavior = false) { const properties = {}; if (!isBehavior) { // 均不指定类型,避免微信小程序 property received type-uncompatible value 警告 builtInProps.forEach((name) => { properties[name] = { type: null, value: '', }; }); // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots properties.uS = { type: null, value: [], observer: function (newVal) { const $slots = Object.create(null); newVal && newVal.forEach((slotName) => { $slots[slotName] = true; }); this.setData({ $slots, }); }, }; } if (options.behaviors) { // wx://form-field if (options.behaviors.includes('swan://form-field')) { properties.name = { type: null, value: '', }; properties.value = { type: null, value: '', }; } } return properties; } function initVirtualHostProps(options) { const properties = {}; return properties; } /** * * @param mpComponentOptions * @param isBehavior */ function initProps(mpComponentOptions) { if (!mpComponentOptions.properties) { mpComponentOptions.properties = {}; } extend(mpComponentOptions.properties, initDefaultProps(mpComponentOptions), initVirtualHostProps(mpComponentOptions.options)); } const PROP_TYPES = [String, Number, Boolean, Object, Array, null]; function parsePropType(type, defaultValue) { // [String]=>String if (isArray(type) && type.length === 1) { return type[0]; } { if ( // [String,Boolean]=>Boolean defaultValue === false && isArray(type) && type.length === 2 && type.indexOf(String) !== -1 && type.indexOf(Boolean) !== -1) { return Boolean; } } return type; } function normalizePropType(type, defaultValue) { const res = parsePropType(type, defaultValue); return PROP_TYPES.indexOf(res) !== -1 ? res : null; } /** * 初始化页面 props,方便接收页面参数,类型均为String,默认值均为'' * @param param * @param rawProps */ function initPageProps({ properties }, rawProps) { if (isArray(rawProps)) { rawProps.forEach((key) => { properties[key] = { type: String, value: '', }; }); } else if (isPlainObject(rawProps)) { Object.keys(rawProps).forEach((key) => { const opts = rawProps[key]; if (isPlainObject(opts)) { // title:{type:String,default:''} let value = opts.default; if (isFunction(value)) { value = value(); } const type = opts.type; opts.type = normalizePropType(type, value); properties[key] = { type: opts.type, value, }; } else { // content:String properties[key] = { type: normalizePropType(opts, null), }; } }); } } function findPropsData(properties, isPage) { return ((isPage ? findPagePropsData(properties) : findComponentPropsData(properties.uP)) || {}); } function findPagePropsData(properties) { const propsData = {}; if (isPlainObject(properties)) { Object.keys(properties).forEach((name) => { if (builtInProps.indexOf(name) === -1) { propsData[name] = properties[name]; } }); } return propsData; } function initFormField(vm) { // 同步 form-field 的 name,value 值 const vueOptions = vm.$options; if (isArray(vueOptions.behaviors) && vueOptions.behaviors.includes('uni://form-field')) { vm.$watch('modelValue', () => { vm.$scope && vm.$scope.setData({ name: vm.name, value: vm.modelValue, }); }, { immediate: true, }); } } function initData(_) { return {}; } function initPropsObserver(componentOptions) { const observe = function observe() { const up = this.properties.uP; if (!up) { return; } if (this.$vm) { updateComponentProps(up, this.$vm.$); } else if (this.properties.uT === 'm') { // 小程序组件 updateMiniProgramComponentProperties(up, this); } }; { componentOptions.properties.uP.observer = observe; } } function updateMiniProgramComponentProperties(up, mpInstance) { const prevProps = mpInstance.properties; const nextProps = findComponentPropsData(up) || {}; if (hasPropsChanged(prevProps, nextProps, false)) { mpInstance.setData(nextProps); } } function updateComponentProps(up, instance) { const prevProps = toRaw(instance.props); const nextProps = findComponentPropsData(up) || {}; if (hasPropsChanged(prevProps, nextProps)) { updateProps(instance, nextProps, prevProps, false); if (hasQueueJob(instance.update)) { invalidateJob(instance.update); } { // 字节跳动小程序 https://github.com/dcloudio/uni-app/issues/3340 // 百度小程序 https://github.com/dcloudio/uni-app/issues/3612 if (!hasQueueJob(instance.update)) { instance.update(); } } } } function hasPropsChanged(prevProps, nextProps, checkLen = true) { const nextKeys = Object.keys(nextProps); if (checkLen && nextKeys.length !== Object.keys(prevProps).length) { return true; } for (let i = 0; i < nextKeys.length; i++) { const key = nextKeys[i]; if (nextProps[key] !== prevProps[key]) { return true; } } return false; } function initBehaviors(vueOptions) { const vueBehaviors = vueOptions.behaviors; let vueProps = vueOptions.props; if (!vueProps) { vueOptions.props = vueProps = []; } const behaviors = []; if (isArray(vueBehaviors)) { vueBehaviors.forEach((behavior) => { behaviors.push(behavior.replace('uni://', 'swan://')); if (behavior === 'uni://form-field') { if (isArray(vueProps)) { vueProps.push('name'); vueProps.push('modelValue'); } else { vueProps.name = { type: String, default: '', }; vueProps.modelValue = { type: [String, Number, Boolean, Array, Object, Date], default: '', }; } } }); } return behaviors; } function applyOptions(componentOptions, vueOptions) { componentOptions.data = initData(); componentOptions.behaviors = initBehaviors(vueOptions); } function parseComponent(vueOptions, { parse, mocks, isPage, initRelation, handleLink, initLifetimes, }) { vueOptions = vueOptions.default || vueOptions; const options = { multipleSlots: true, addGlobalClass: true, pureDataPattern: /^uP$/, }; if (vueOptions.options) { extend(options, vueOptions.options); } const mpComponentOptions = { options, lifetimes: initLifetimes({ mocks, isPage, initRelation, vueOptions }), pageLifetimes: { show() { this.$vm && this.$vm.$callHook('onPageShow'); }, hide() { this.$vm && this.$vm.$callHook('onPageHide'); }, resize(size) { this.$vm && this.$vm.$callHook('onPageResize', size); }, }, methods: { __l: handleLink, }, }; if (__VUE_OPTIONS_API__) { applyOptions(mpComponentOptions, vueOptions); } initProps(mpComponentOptions); initPropsObserver(mpComponentOptions); initExtraOptions(mpComponentOptions, vueOptions); initWxsCallMethods(mpComponentOptions.methods, vueOptions.wxsCallMethods); if (parse) { parse(mpComponentOptions, { handleLink }); } return mpComponentOptions; } function initCreateComponent(parseOptions) { return function createComponent(vueComponentOptions) { return Component(parseComponent(vueComponentOptions, parseOptions)); }; } let $createComponentFn; let $destroyComponentFn; function getAppVm() { if (process.env.UNI_MP_PLUGIN) { return swan.$vm; } if (process.env.UNI_SUBPACKAGE) { return swan.$subpackages[process.env.UNI_SUBPACKAGE].$vm; } return getApp().$vm; } function $createComponent(initialVNode, options) { if (!$createComponentFn) { $createComponentFn = getAppVm().$createComponent; } const proxy = $createComponentFn(initialVNode, options); return getExposeProxy(proxy.$) || proxy; } function $destroyComponent(instance) { if (!$destroyComponentFn) { $destroyComponentFn = getAppVm().$destroyComponent; } return $destroyComponentFn(instance); } function parsePage(vueOptions, parseOptions) { const { parse, mocks, isPage, initRelation, handleLink, initLifetimes } = parseOptions; const miniProgramPageOptions = parseComponent(vueOptions, { mocks, isPage, initRelation, handleLink, initLifetimes, }); initPageProps(miniProgramPageOptions, (vueOptions.default || vueOptions).props); const methods = miniProgramPageOptions.methods; methods.onLoad = function (query) { this.options = query; this.$page = { fullPath: addLeadingSlash(this.route + stringifyQuery(query)), }; return this.$vm && this.$vm.$callHook(ON_LOAD, query); }; initHooks(methods, PAGE_INIT_HOOKS); { initUnknownHooks(methods, vueOptions, [ON_INIT, ON_READY]); } initRuntimeHooks(methods, vueOptions.__runtimeHooks); initMixinRuntimeHooks(methods); parse && parse(miniProgramPageOptions, { handleLink }); return miniProgramPageOptions; } function initCreatePage(parseOptions) { return function createPage(vuePageOptions) { return Component(parsePage(vuePageOptions, parseOptions)); }; } /** * 用于延迟调用 setData * 在 setData 真实调用的时机需执行 fixSetDataEnd * @param {*} mpInstance */ function fixSetDataStart(mpInstance) { const setData = mpInstance.setData; const setDataArgs = []; mpInstance.setData = function () { setDataArgs.push(arguments); }; mpInstance.__fixInitData = function () { this.setData = setData; const fn = () => { setDataArgs.forEach((args) => { setData.apply(this, args); }); }; if (setDataArgs.length) { if (this.groupSetData) { this.groupSetData(fn); } else { fn(); } } }; } /** * 恢复真实的 setData 方法 * @param {*} mpInstance */ function fixSetDataEnd(mpInstance) { if (mpInstance.__fixInitData) { mpInstance.__fixInitData(); delete mpInstance.__fixInitData; } } const MPPage = Page; const MPComponent = Component; function initTriggerEvent(mpInstance) { const oldTriggerEvent = mpInstance.triggerEvent; mpInstance.triggerEvent = function (event, ...args) { return oldTriggerEvent.apply(mpInstance, [customizeEvent(event), ...args]); }; } function initMiniProgramHook(name, options, isComponent) { const oldHook = options[name]; if (!oldHook) { options[name] = function () { initTriggerEvent(this); }; } else { options[name] = function (...args) { initTriggerEvent(this); return oldHook.apply(this, args); }; } } Page = function (options) { initMiniProgramHook(ON_LOAD, options); return MPPage(options); }; { Page.after = MPPage.after; } Component = function (options) { initMiniProgramHook('created', options); // 小程序组件 const isVueComponent = options.properties && options.properties.uP; if (!isVueComponent) { initProps(options); initPropsObserver(options); } return MPComponent(options); }; function parse$2(appOptions) { // 百度 onShow 竟然会在 onLaunch 之前 appOptions.onShow = function onShow(args) { if (!this.$vm) { this.onLaunch(args); } this.$vm.$callHook(ON_SHOW, args); }; } var parseAppOptions = /*#__PURE__*/Object.freeze({ __proto__: null, parse: parse$2 }); // @ts-ignore function initLifetimes({ mocks, isPage, initRelation, vueOptions, }) { return { attached() { // 微信 和 QQ 不需要延迟 setRef { initSetRef(this); } let properties = this.properties; initVueIds(properties.uI, this); const relationOptions = { vuePid: this._$vuePid, }; // 处理父子关系 initRelation(this, relationOptions); // 初始化 vue 实例 const mpInstance = this; const isMiniProgramPage = isPage(mpInstance); let propsData = properties; if (isMiniProgramPage) { { propsData = this.pageinstance._$props; delete this.pageinstance._$props; } } this.$vm = $createComponent({ type: vueOptions, props: findPropsData(propsData, isMiniProgramPage), }, { mpType: isMiniProgramPage ? 'page' : 'component', mpInstance, slots: properties.uS || {}, parentComponent: relationOptions.parent && relationOptions.parent.$, onBeforeSetup(instance, options) { initRefs(instance, mpInstance); initMocks(instance, mpInstance, mocks); initComponentInstance(instance, options); }, }); if (!isMiniProgramPage) { initFormField(this.$vm); } }, ready() { // 当组件 props 默认值为 true,初始化时传入 false 会导致 created,ready 触发, 但 attached 不触发 // https://developers.weixin.qq.com/community/develop/doc/00066ae2844cc0f8eb883e2a557800 if (this.$vm) { { nextSetDataTick(this, () => { this.$vm.$callHook('mounted'); this.$vm.$callHook(ON_READY); }); } } }, detached() { if (this.$vm) { pruneComponentPropsCache(this.$vm.$.uid); $destroyComponent(this.$vm); } }, }; } function handleLink(event) { // detail 是微信,value 是百度(dipatch) const detail = (event.detail || event.value); const vuePid = detail.vuePid; let parentVm; if (vuePid) { parentVm = findVmByVueId(this.$vm, vuePid); } if (!parentVm) { parentVm = this.$vm; } detail.parent = parentVm; } const mocks = ['nodeId', 'componentName', '_componentId', 'uniquePrefix']; function isPage(mpInstance) { return !!mpInstance.methods.onLoad; } function initRelation(mpInstance, detail) { mpInstance.dispatch('__l', detail); } const newLifecycle = /*#__PURE__*/ swan.canIUse('lifecycle-2-0'); function parse$1(componentOptions) { const methods = componentOptions.methods; const lifetimes = componentOptions.lifetimes; // 关于百度小程序生命周期的说明(组件作为页面时): // lifetimes:attached --> methods:onShow --> methods:onLoad --> methods:onReady // 这里在强制将onShow挪到onLoad之后触发,另外一处修改在page-parser.js const oldAttached = lifetimes.attached; // 百度小程序基础库 3.260 以上支持页面 onInit 生命周期,提前创建 vm 实例 lifetimes.onInit = function onInit(query) { // 百度小程序后续可能移除 pageinstance 属性,为向后兼容进行补充 if (!this.pageinstance || !this.pageinstance.setData) { const pages = getCurrentPages(); this.pageinstance = pages[pages.length - 1]; } this.pageinstance._$props = query; // 处理百度小程序 onInit 生命周期调用 setData 无效的问题 fixSetDataStart(this); oldAttached.call(this); this.pageinstance.$vm = this.$vm; this.$vm.$callHook(ON_INIT, query); }; lifetimes.attached = function attached() { if (!this.$vm) { oldAttached.call(this); } else { initMocks(this.$vm.$, this, mocks); fixSetDataEnd(this); } if (isPage(this) && this.$vm) { // 百度 onLoad 在 attached 之前触发(基础库小于 3.70) // 百度 当组件作为页面时 pageinstance 不是原来组件的 instance const pageInstance = this.pageinstance; pageInstance.$vm = this.$vm; if (hasOwn(pageInstance, '_$args')) { this.$vm.$callHook(ON_LOAD, pageInstance._$args); this.$vm.$callHook(ON_SHOW); delete pageInstance._$args; } } else { // 百度小程序组件不触发 methods 内的 onReady if (this.$vm) { nextSetDataTick(this, () => { this.$vm.$callHook('mounted'); }); } } }; if (newLifecycle) { methods.onReady = lifetimes.ready; delete lifetimes.ready; } componentOptions.messages = { __l: methods.__l, }; delete methods.__l; // 百度小程序自定义组件,不支持绑定动态事件,故由 __e 分发 methods.__e = handleEvent; } var parseComponentOptions = /*#__PURE__*/Object.freeze({ __proto__: null, mocks: mocks, isPage: isPage, initRelation: initRelation, parse: parse$1, handleLink: handleLink, initLifetimes: initLifetimes }); function parse(pageOptions) { parse$1(pageOptions); const methods = pageOptions.methods; // 纠正百度小程序生命周期methods:onShow在methods:onLoad之前触发的问题 methods.onShow = function onShow() { if (this.$vm && this._$loaded) { this.$vm.$callHook(ON_SHOW); } }; methods.onLoad = function onLoad(query) { // 百度 onLoad 在 attached 之前触发,先存储 args, 在 attached 里边触发 onLoad if (this.$vm) { this._$loaded = true; const copyQuery = extend({}, query); delete copyQuery.__id__; this.options = copyQuery; this.pageinstance.$page = this.$page = { fullPath: '/' + this.pageinstance.route + stringifyQuery(copyQuery), }; this.$vm.$callHook(ON_LOAD, query); this.$vm.$callHook(ON_SHOW); } else { this.pageinstance._$args = query; } }; } var parsePageOptions = /*#__PURE__*/Object.freeze({ __proto__: null, parse: parse, handleLink: handleLink, initLifetimes: initLifetimes, mocks: mocks, isPage: isPage, initRelation: initRelation }); const createApp = initCreateApp(parseAppOptions); const createPage = initCreatePage(parsePageOptions); const createComponent = initCreateComponent(parseComponentOptions); const createSubpackageApp = initCreateSubpackageApp(parseAppOptions); swan.EventChannel = EventChannel; swan.createApp = global.createApp = createApp; swan.createPage = createPage; swan.createComponent = createComponent; swan.createSubpackageApp = global.createSubpackageApp = createSubpackageApp; export { createApp, createComponent, createPage, createSubpackageApp };