You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

1115 lines
35 KiB

import { SLOT_DEFAULT_NAME, EventChannel, invokeArrayFns, MINI_PROGRAM_PAGE_RUNTIME_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, 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, isFunction, hasOwn, extend, hyphenate, isPlainObject, isObject } from '@vue/shared';
import { ref, nextTick, findComponentPropsData, toRaw, updateProps, hasQueueJob, invalidateJob, devtoolsComponentAdded, 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__ &&
isFunction(swan.getEventChannel)) {
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 = isFunction(getApp) && 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.$;
if (__VUE_PROD_DEVTOOLS__) {
// 定制 App 的 $children
Object.defineProperty(internalInstance.ctx, '$children', {
get() {
return getCurrentPages().map((page) => page.$vm);
},
});
}
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 = isFunction(getApp) &&
getApp({
allowDefault: true,
});
if (!app)
return;
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, currentTarget: { 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')) {
if (!options.properties || !options.properties.name) {
properties.name = {
type: null,
value: '',
};
}
if (!options.properties || !options.properties.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,
// styleIsolation: 'apply-shared',
addGlobalClass: true,
pureDataPattern: /^uP$/,
};
if (isArray(vueOptions.mixins)) {
vueOptions.mixins.forEach((item) => {
if (isObject(item.options)) {
extend(options, item.options);
}
});
}
if (vueOptions.options) {
extend(options, vueOptions.options);
}
const mpComponentOptions = {
options,
lifetimes: initLifetimes({ mocks, isPage, initRelation, vueOptions }),
pageLifetimes: {
show() {
if (__VUE_PROD_DEVTOOLS__) {
devtoolsComponentAdded(this.$vm.$);
}
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;
const newTriggerEvent = function (event, ...args) {
return oldTriggerEvent.apply(mpInstance, [customizeEvent(event), ...args]);
};
// 京东小程序triggerEvent为只读属性
try {
mpInstance.triggerEvent = newTriggerEvent;
}
catch (error) {
mpInstance._triggerEvent = newTriggerEvent;
}
}
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,
handleLink: handleLink,
initLifetimes: initLifetimes,
initRelation: initRelation,
isPage: isPage,
mocks: mocks,
parse: parse$1
});
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,
handleLink: handleLink,
initLifetimes: initLifetimes,
initRelation: initRelation,
isPage: isPage,
mocks: mocks,
parse: parse
});
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 };