uni.mp.esm.js 34.9 KB
Newer Older
fxy060608's avatar
fxy060608 已提交
1
import { isPlainObject, isArray, hasOwn, isFunction, extend, camelize, isObject } from '@vue/shared';
fxy060608's avatar
fxy060608 已提交
2
import { injectHook, ref } from 'vue';
fxy060608's avatar
fxy060608 已提交
3

fxy060608's avatar
fxy060608 已提交
4 5 6 7 8 9 10 11 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 64 65 66 67 68
const ON_READY$1 = 'onReady';

class EventChannel$1 {
    constructor(id, events) {
        this.id = id;
        this.listener = {};
        this.emitCache = {};
        if (events) {
            Object.keys(events).forEach((name) => {
                this.on(name, events[name]);
            });
        }
    }
    emit(eventName, ...args) {
        const fns = this.listener[eventName];
        if (!fns) {
            return (this.emitCache[eventName] || (this.emitCache[eventName] = [])).push(args);
        }
        fns.forEach((opt) => {
            opt.fn.apply(opt.fn, args);
        });
        this.listener[eventName] = fns.filter((opt) => opt.type !== 'once');
    }
    on(eventName, fn) {
        this._addListener(eventName, 'on', fn);
        this._clearCache(eventName);
    }
    once(eventName, fn) {
        this._addListener(eventName, 'once', fn);
        this._clearCache(eventName);
    }
    off(eventName, fn) {
        const fns = this.listener[eventName];
        if (!fns) {
            return;
        }
        if (fn) {
            for (let i = 0; i < fns.length;) {
                if (fns[i].fn === fn) {
                    fns.splice(i, 1);
                    i--;
                }
                i++;
            }
        }
        else {
            delete this.listener[eventName];
        }
    }
    _clearCache(eventName) {
        const cacheArgs = this.emitCache[eventName];
        if (cacheArgs) {
            for (; cacheArgs.length > 0;) {
                this.emit.apply(this, [eventName, ...cacheArgs.shift()]);
            }
        }
    }
    _addListener(eventName, type, fn) {
        (this.listener[eventName] || (this.listener[eventName] = [])).push({
            fn,
            type,
        });
    }
}

fxy060608's avatar
fxy060608 已提交
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
// quickapp-webview 不能使用 default 作为插槽名称
const SLOT_DEFAULT_NAME = 'd';
// lifecycle
// App and Page
const ON_SHOW = 'onShow';
const ON_HIDE = 'onHide';
//App
const ON_LAUNCH = 'onLaunch';
const ON_ERROR = 'onError';
const ON_THEME_CHANGE = 'onThemeChange';
const ON_PAGE_NOT_FOUND = 'onPageNotFound';
const ON_UNHANDLE_REJECTION = 'onUnhandledRejection';
//Page
const ON_LOAD = 'onLoad';
const ON_READY = 'onReady';
const ON_UNLOAD = 'onUnload';
const ON_RESIZE = 'onResize';
const ON_TAB_ITEM_TAP = 'onTabItemTap';
const ON_REACH_BOTTOM = 'onReachBottom';
const ON_PULL_DOWN_REFRESH = 'onPullDownRefresh';
fxy060608's avatar
fxy060608 已提交
89
const ON_ADD_TO_FAVORITES = 'onAddToFavorites';
fxy060608's avatar
fxy060608 已提交
90

fxy060608's avatar
fxy060608 已提交
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
const encode = encodeURIComponent;
function stringifyQuery(obj, encodeStr = encode) {
    const res = obj
        ? Object.keys(obj)
            .map((key) => {
            let val = obj[key];
            if (typeof val === undefined || val === null) {
                val = '';
            }
            else if (isPlainObject(val)) {
                val = JSON.stringify(val);
            }
            return encodeStr(key) + '=' + encodeStr(val);
        })
            .filter((x) => x.length > 0)
            .join('&')
        : null;
    return res ? `?${res}` : '';
fxy060608's avatar
fxy060608 已提交
109 110
}

fxy060608's avatar
fxy060608 已提交
111 112 113 114 115 116
const invokeArrayFns = (fns, arg) => {
    let ret;
    for (let i = 0; i < fns.length; i++) {
        ret = fns[i](arg);
    }
    return ret;
fxy060608's avatar
fxy060608 已提交
117
};
fxy060608's avatar
fxy060608 已提交
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

class EventChannel {
    constructor(id, events) {
        this.id = id;
        this.listener = {};
        this.emitCache = {};
        if (events) {
            Object.keys(events).forEach((name) => {
                this.on(name, events[name]);
            });
        }
    }
    emit(eventName, ...args) {
        const fns = this.listener[eventName];
        if (!fns) {
            return (this.emitCache[eventName] || (this.emitCache[eventName] = [])).push(args);
        }
        fns.forEach((opt) => {
            opt.fn.apply(opt.fn, args);
        });
        this.listener[eventName] = fns.filter((opt) => opt.type !== 'once');
    }
    on(eventName, fn) {
        this._addListener(eventName, 'on', fn);
        this._clearCache(eventName);
    }
    once(eventName, fn) {
        this._addListener(eventName, 'once', fn);
        this._clearCache(eventName);
    }
    off(eventName, fn) {
        const fns = this.listener[eventName];
        if (!fns) {
            return;
        }
        if (fn) {
            for (let i = 0; i < fns.length;) {
                if (fns[i].fn === fn) {
                    fns.splice(i, 1);
                    i--;
                }
                i++;
            }
        }
        else {
            delete this.listener[eventName];
        }
    }
    _clearCache(eventName) {
        const cacheArgs = this.emitCache[eventName];
        if (cacheArgs) {
            for (; cacheArgs.length > 0;) {
                this.emit.apply(this, [eventName, ...cacheArgs.shift()]);
            }
        }
    }
    _addListener(eventName, type, fn) {
        (this.listener[eventName] || (this.listener[eventName] = [])).push({
            fn,
            type,
        });
    }
}

const eventChannels = {};
const eventChannelStack = [];
function getEventChannel(id) {
    if (id) {
        const eventChannel = eventChannels[id];
        delete eventChannels[id];
        return eventChannel;
    }
    return eventChannelStack.shift();
}
fxy060608's avatar
fxy060608 已提交
192

fxy060608's avatar
fxy060608 已提交
193 194 195 196
const MP_METHODS = [
    'createSelectorQuery',
    'createIntersectionObserver',
    'selectAllComponents',
197
    'selectComponent',
fxy060608's avatar
fxy060608 已提交
198 199 200
];
function createEmitFn(oldEmit, ctx) {
    return function emit(event, ...args) {
fxy060608's avatar
fxy060608 已提交
201 202 203
        const scope = ctx.$scope;
        if (scope && event) {
            const detail = { __args__: args };
fxy060608's avatar
fxy060608 已提交
204 205 206
            {
                scope.triggerEvent(event, detail);
            }
fxy060608's avatar
fxy060608 已提交
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
        }
        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.$scope = options.mpInstance;
    // TODO @deprecated
    ctx.$mp = {};
    if (__VUE_OPTIONS_API__) {
        ctx._self = {};
    }
    // $vm
    ctx.$scope.$vm = instance.proxy;
    // slots
fxy060608's avatar
fxy060608 已提交
225 226 227 228 229 230 231
    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;
fxy060608's avatar
fxy060608 已提交
232 233
        }
    }
fxy060608's avatar
fxy060608 已提交
234 235 236 237 238 239 240 241
    ctx.getOpenerEventChannel = function () {
        if (!this.__eventChannel__) {
            this.__eventChannel__ = new EventChannel();
        }
        return this.__eventChannel__;
    };
    ctx.$hasHook = hasHook;
    ctx.$callHook = callHook;
fxy060608's avatar
fxy060608 已提交
242 243 244 245 246 247
    // $emit
    instance.emit = createEmitFn(instance.emit, ctx);
}
function initComponentInstance(instance, options) {
    initBaseInstance(instance, options);
    const ctx = instance.ctx;
248
    MP_METHODS.forEach((method) => {
fxy060608's avatar
fxy060608 已提交
249 250 251 252 253 254 255 256 257 258
        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;
259
    mocks.forEach((mock) => {
fxy060608's avatar
fxy060608 已提交
260
        if (hasOwn(mpInstance, mock)) {
261
            instance[mock] = ctx[mock] = mpInstance[mock];
fxy060608's avatar
fxy060608 已提交
262 263
        }
    });
fxy060608's avatar
fxy060608 已提交
264
}
fxy060608's avatar
fxy060608 已提交
265 266 267 268 269 270 271 272
function hasHook(name) {
    const hooks = this.$[name];
    if (hooks && hooks.length) {
        return true;
    }
    return false;
}
function callHook(name, args) {
fxy060608's avatar
fxy060608 已提交
273 274 275 276 277 278
    if (name === 'mounted') {
        callHook.call(this, 'bm'); // beforeMount
        this.$.isMounted = true;
        name = 'm';
    }
    else if (name === 'onLoad' && args && args.__id__) {
fxy060608's avatar
fxy060608 已提交
279 280 281 282 283 284
        this.__eventChannel__ = getEventChannel(args.__id__);
        delete args.__id__;
    }
    const hooks = this.$[name];
    return hooks && invokeArrayFns(hooks, args);
}
fxy060608's avatar
fxy060608 已提交
285

fxy060608's avatar
fxy060608 已提交
286
const PAGE_HOOKS = [
fxy060608's avatar
fxy060608 已提交
287 288 289 290 291 292 293 294 295
    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,
fxy060608's avatar
fxy060608 已提交
296 297 298 299
    // 'onReady', // lifetimes.ready
    // 'onPageScroll', // 影响性能,开发者手动注册
    // 'onShareTimeline', // 右上角菜单,开发者手动注册
    // 'onShareAppMessage' // 右上角菜单,开发者手动注册
fxy060608's avatar
fxy060608 已提交
300 301 302
];
function findHooks(vueOptions, hooks = new Set()) {
    if (vueOptions) {
303
        Object.keys(vueOptions).forEach((name) => {
fxy060608's avatar
fxy060608 已提交
304 305 306 307 308 309 310
            if (name.indexOf('on') === 0 && isFunction(vueOptions[name])) {
                hooks.add(name);
            }
        });
        if (__VUE_OPTIONS_API__) {
            const { extends: extendsOptions, mixins } = vueOptions;
            if (mixins) {
311
                mixins.forEach((mixin) => findHooks(mixin, hooks));
fxy060608's avatar
fxy060608 已提交
312 313 314 315 316 317 318 319
            }
            if (extendsOptions) {
                findHooks(extendsOptions, hooks);
            }
        }
    }
    return hooks;
}
320
function initHook$1(mpOptions, hook, excludes) {
fxy060608's avatar
fxy060608 已提交
321 322
    if (excludes.indexOf(hook) === -1 && !hasOwn(mpOptions, hook)) {
        mpOptions[hook] = function (args) {
323
            if (hook === 'onError') {
fxy060608's avatar
fxy060608 已提交
324 325 326 327 328 329
                return getApp().$vm.$callHook(hook, args);
            }
            return this.$vm && this.$vm.$callHook(hook, args);
        };
    }
}
fxy060608's avatar
fxy060608 已提交
330
const EXCLUDE_HOOKS = [ON_READY];
fxy060608's avatar
fxy060608 已提交
331
function initHooks(mpOptions, hooks, excludes = EXCLUDE_HOOKS) {
332
    hooks.forEach((hook) => initHook$1(mpOptions, hook, excludes));
fxy060608's avatar
fxy060608 已提交
333 334
}
function initUnknownHooks(mpOptions, vueOptions, excludes = EXCLUDE_HOOKS) {
335
    findHooks(vueOptions).forEach((hook) => initHook$1(mpOptions, hook, excludes));
fxy060608's avatar
fxy060608 已提交
336 337
}

fxy060608's avatar
fxy060608 已提交
338 339 340 341 342 343 344
tt.appLaunchHooks = [];
function injectAppLaunchHooks(appInstance) {
    tt.appLaunchHooks.forEach((hook) => {
        injectHook(ON_LAUNCH, hook, appInstance);
    });
}

fxy060608's avatar
fxy060608 已提交
345
const HOOKS = [
fxy060608's avatar
fxy060608 已提交
346 347 348 349 350 351
    ON_SHOW,
    ON_HIDE,
    ON_ERROR,
    ON_THEME_CHANGE,
    ON_PAGE_NOT_FOUND,
    ON_UNHANDLE_REJECTION,
fxy060608's avatar
fxy060608 已提交
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366
];
function parseApp(instance, parseAppOptions) {
    const internalInstance = instance.$;
    const appOptions = {
        globalData: (instance.$options && instance.$options.globalData) || {},
        $vm: instance,
        onLaunch(options) {
            const ctx = internalInstance.ctx;
            if (this.$vm && ctx.$scope) {
                // 已经初始化过了,主要是为了百度,百度 onShow 在 onLaunch 之前
                return;
            }
            initBaseInstance(internalInstance, {
                mpType: 'app',
                mpInstance: this,
367
                slots: [],
fxy060608's avatar
fxy060608 已提交
368
            });
fxy060608's avatar
fxy060608 已提交
369
            injectAppLaunchHooks(internalInstance);
fxy060608's avatar
fxy060608 已提交
370
            ctx.globalData = this.globalData;
371
            instance.$callHook(ON_LAUNCH, extend({ app: { mixin: internalInstance.appContext.app.mixin } }, options));
372
        },
fxy060608's avatar
fxy060608 已提交
373
    };
fxy060608's avatar
fxy060608 已提交
374
    initLocale(instance);
fxy060608's avatar
fxy060608 已提交
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390
    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));
    };
fxy060608's avatar
fxy060608 已提交
391
}
fxy060608's avatar
fxy060608 已提交
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428
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];
            }
        });
        if (isFunction(appOptions.onShow) && tt.onAppShow) {
            tt.onAppShow((args) => {
                vm.$callHook('onShow', args);
            });
        }
        if (isFunction(appOptions.onHide) && tt.onAppHide) {
            tt.onAppHide((args) => {
                vm.$callHook('onHide', args);
            });
        }
        if (isFunction(appOptions.onLaunch)) {
            const args = tt.getLaunchOptionsSync && tt.getLaunchOptionsSync();
            vm.$callHook('onLaunch', args);
        }
        return App(appOptions);
    };
}
fxy060608's avatar
fxy060608 已提交
429
function initLocale(appVm) {
fxy060608's avatar
fxy060608 已提交
430
    const locale = ref(tt.getSystemInfoSync().language || 'zh-Hans');
fxy060608's avatar
fxy060608 已提交
431 432 433 434 435 436 437 438
    Object.defineProperty(appVm, '$locale', {
        get() {
            return locale.value;
        },
        set(v) {
            locale.value = v;
        },
    });
fxy060608's avatar
fxy060608 已提交
439 440
}

fxy060608's avatar
fxy060608 已提交
441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478
function initBehavior(options) {
    return Behavior(options);
}
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) => {
fxy060608's avatar
fxy060608 已提交
479
        const ref = component.dataset.r;
fxy060608's avatar
fxy060608 已提交
480 481 482 483 484 485 486
        $refs[ref] = component.$vm || component;
    });
}
function initRefs(instance, mpInstance) {
    Object.defineProperty(instance, 'refs', {
        get() {
            const $refs = {};
fxy060608's avatar
fxy060608 已提交
487 488
            selectAllComponents(mpInstance, '.r', $refs);
            const forComponents = mpInstance.selectAllComponents('.r-i-f');
fxy060608's avatar
fxy060608 已提交
489
            forComponents.forEach((component) => {
fxy060608's avatar
fxy060608 已提交
490
                const ref = component.dataset.r;
fxy060608's avatar
fxy060608 已提交
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517
                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;
        }
    }
518 519 520 521 522 523 524 525 526 527
}
/**
 * @param properties
 */
function fixProperties(properties) {
    Object.keys(properties).forEach((name) => {
        if (properties[name] === null) {
            properties[name] = undefined;
        }
    });
fxy060608's avatar
fxy060608 已提交
528 529
}

fxy060608's avatar
fxy060608 已提交
530
const PROP_TYPES = [String, Number, Boolean, Object, Array, null];
fxy060608's avatar
fxy060608 已提交
531 532
function createObserver(name) {
    return function observer(newVal) {
fxy060608's avatar
fxy060608 已提交
533 534 535 536 537 538 539 540 541 542
        const { $vm } = this;
        if ($vm) {
            // 为了触发其他非 render watcher
            const instance = $vm.$;
            // 飞书小程序初始化太慢,导致 observer 触发时,vue 组件的 created 可能还没触发,此时开发者可能已经定义了 watch
            // 但因为 created 还没触发,导致部分组件出错,如 uni-collapse,在 created 中初始化了 this.children
            // 自定义 watch 中使用了 this.children
            {
                instance.props[name] = newVal;
            }
fxy060608's avatar
fxy060608 已提交
543 544 545
        }
    };
}
fxy060608's avatar
fxy060608 已提交
546 547 548 549 550 551 552 553 554 555 556
function parsePropType(type, defaultValue) {
    // [String]=>String
    if (isArray(type) && type.length === 1) {
        return type[0];
    }
    return type;
}
function normalizePropType(type, defaultValue) {
    const res = parsePropType(type);
    return PROP_TYPES.indexOf(res) !== -1 ? res : null;
}
fxy060608's avatar
fxy060608 已提交
557 558 559
function initDefaultProps(isBehavior = false) {
    const properties = {};
    if (!isBehavior) {
fxy060608's avatar
fxy060608 已提交
560
        properties.uI = {
fxy060608's avatar
fxy060608 已提交
561
            type: null,
562
            value: '',
fxy060608's avatar
fxy060608 已提交
563 564
        };
        // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
fxy060608's avatar
fxy060608 已提交
565
        properties.uS = {
fxy060608's avatar
fxy060608 已提交
566 567 568 569
            type: null,
            value: [],
            observer: function (newVal) {
                const $slots = Object.create(null);
fxy060608's avatar
fxy060608 已提交
570 571 572 573
                newVal &&
                    newVal.forEach((slotName) => {
                        $slots[slotName] = true;
                    });
fxy060608's avatar
fxy060608 已提交
574
                this.setData({
575
                    $slots,
fxy060608's avatar
fxy060608 已提交
576
                });
577
            },
fxy060608's avatar
fxy060608 已提交
578 579 580 581 582 583 584 585
        };
    }
    return properties;
}
function createProperty(key, prop) {
    prop.observer = createObserver(key);
    return prop;
}
fxy060608's avatar
fxy060608 已提交
586
/**
fxy060608's avatar
fxy060608 已提交
587
 *
fxy060608's avatar
fxy060608 已提交
588 589 590 591
 * @param mpComponentOptions
 * @param rawProps
 * @param isBehavior
 */
fxy060608's avatar
fxy060608 已提交
592 593 594
function initProps(mpComponentOptions, rawProps, isBehavior = false) {
    const properties = initDefaultProps(isBehavior);
    if (isArray(rawProps)) {
595
        rawProps.forEach((key) => {
fxy060608's avatar
fxy060608 已提交
596
            properties[key] = createProperty(key, {
597
                type: null,
fxy060608's avatar
fxy060608 已提交
598 599 600 601
            });
        });
    }
    else if (isPlainObject(rawProps)) {
602
        Object.keys(rawProps).forEach((key) => {
fxy060608's avatar
fxy060608 已提交
603 604 605 606 607 608 609
            const opts = rawProps[key];
            if (isPlainObject(opts)) {
                // title:{type:String,default:''}
                let value = opts.default;
                if (isFunction(value)) {
                    value = value();
                }
fxy060608's avatar
fxy060608 已提交
610 611
                const type = opts.type;
                opts.type = normalizePropType(type);
fxy060608's avatar
fxy060608 已提交
612
                properties[key] = createProperty(key, {
fxy060608's avatar
fxy060608 已提交
613
                    type: opts.type,
614
                    value,
fxy060608's avatar
fxy060608 已提交
615 616 617 618 619
                });
            }
            else {
                // content:String
                properties[key] = createProperty(key, {
fxy060608's avatar
fxy060608 已提交
620
                    type: normalizePropType(opts),
fxy060608's avatar
fxy060608 已提交
621 622 623 624 625
                });
            }
        });
    }
    mpComponentOptions.properties = properties;
fxy060608's avatar
fxy060608 已提交
626 627
}

fxy060608's avatar
fxy060608 已提交
628 629 630 631
function initData(vueOptions) {
    let data = vueOptions.data || {};
    if (typeof data === 'function') {
        try {
632
            const appConfig = getApp().$vm.$.appContext.config;
fxy060608's avatar
fxy060608 已提交
633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662
            data = data.call(appConfig.globalProperties);
        }
        catch (e) {
            if (process.env.VUE_APP_DEBUG) {
                console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data, e);
            }
        }
    }
    else {
        try {
            // 对 data 格式化
            data = JSON.parse(JSON.stringify(data));
        }
        catch (e) { }
    }
    if (!isPlainObject(data)) {
        data = {};
    }
    return data;
}
function initBehaviors(vueOptions, initBehavior) {
    const vueBehaviors = vueOptions.behaviors;
    const vueExtends = vueOptions.extends;
    const vueMixins = vueOptions.mixins;
    let vueProps = vueOptions.props;
    if (!vueProps) {
        vueOptions.props = vueProps = [];
    }
    const behaviors = [];
    if (isArray(vueBehaviors)) {
663
        vueBehaviors.forEach((behavior) => {
fxy060608's avatar
fxy060608 已提交
664 665 666 667 668 669 670 671 672
            behaviors.push(behavior.replace('uni://', `${__PLATFORM_PREFIX__}://`));
            if (behavior === 'uni://form-field') {
                if (isArray(vueProps)) {
                    vueProps.push('name');
                    vueProps.push('value');
                }
                else {
                    vueProps.name = {
                        type: String,
673
                        default: '',
fxy060608's avatar
fxy060608 已提交
674 675 676
                    };
                    vueProps.value = {
                        type: [String, Number, Boolean, Array, Object, Date],
677
                        default: '',
fxy060608's avatar
fxy060608 已提交
678 679 680 681 682
                    };
                }
            }
        });
    }
fxy060608's avatar
fxy060608 已提交
683
    if (vueExtends && vueExtends.props) {
fxy060608's avatar
fxy060608 已提交
684 685 686 687 688
        const behavior = {};
        initProps(behavior, vueExtends.props, true);
        behaviors.push(initBehavior(behavior));
    }
    if (isArray(vueMixins)) {
689
        vueMixins.forEach((vueMixin) => {
690
            if (vueMixin.props) {
fxy060608's avatar
fxy060608 已提交
691 692 693 694 695 696 697 698 699 700 701
                const behavior = {};
                initProps(behavior, vueMixin.props, true);
                behaviors.push(initBehavior(behavior));
            }
        });
    }
    return behaviors;
}
function applyOptions(componentOptions, vueOptions, initBehavior) {
    componentOptions.data = initData(vueOptions);
    componentOptions.behaviors = initBehaviors(vueOptions, initBehavior);
fxy060608's avatar
fxy060608 已提交
702 703
}

704
function parseComponent(vueOptions, { parse, mocks, isPage, initRelation, handleLink, initLifetimes, }) {
fxy060608's avatar
fxy060608 已提交
705 706 707
    vueOptions = vueOptions.default || vueOptions;
    const options = {
        multipleSlots: true,
708
        addGlobalClass: true,
fxy060608's avatar
fxy060608 已提交
709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724
    };
    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);
725
            },
fxy060608's avatar
fxy060608 已提交
726 727 728
        },
        methods: {
            __l: handleLink,
729
        },
fxy060608's avatar
fxy060608 已提交
730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759
    };
    if (__VUE_OPTIONS_API__) {
        applyOptions(mpComponentOptions, vueOptions, initBehavior);
    }
    initProps(mpComponentOptions, vueOptions.props, false);
    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 $createComponent(initialVNode, options) {
    if (!$createComponentFn) {
        $createComponentFn = getApp().$vm.$createComponent;
    }
    return $createComponentFn(initialVNode, options);
}
function $destroyComponent(instance) {
    if (!$destroyComponentFn) {
        $destroyComponentFn = getApp().$vm.$destroyComponent;
    }
    return $destroyComponentFn(instance);
fxy060608's avatar
fxy060608 已提交
760 761
}

fxy060608's avatar
fxy060608 已提交
762
function parsePage(vueOptions, parseOptions) {
763
    const { parse, mocks, isPage, initRelation, handleLink, initLifetimes } = parseOptions;
fxy060608's avatar
fxy060608 已提交
764 765 766 767 768
    const miniProgramPageOptions = parseComponent(vueOptions, {
        mocks,
        isPage,
        initRelation,
        handleLink,
769
        initLifetimes,
fxy060608's avatar
fxy060608 已提交
770 771 772 773 774
    });
    const methods = miniProgramPageOptions.methods;
    methods.onLoad = function (query) {
        this.options = query;
        this.$page = {
775
            fullPath: '/' + this.route + stringifyQuery(query),
fxy060608's avatar
fxy060608 已提交
776
        };
fxy060608's avatar
fxy060608 已提交
777
        return this.$vm && this.$vm.$callHook(ON_LOAD, query);
fxy060608's avatar
fxy060608 已提交
778 779 780 781 782 783 784 785 786 787
    };
    initHooks(methods, PAGE_HOOKS);
    initUnknownHooks(methods, vueOptions);
    parse && parse(miniProgramPageOptions, { handleLink });
    return miniProgramPageOptions;
}
function initCreatePage(parseOptions) {
    return function createPage(vuePageOptions) {
        return Component(parsePage(vuePageOptions, parseOptions));
    };
fxy060608's avatar
fxy060608 已提交
788 789
}

fxy060608's avatar
fxy060608 已提交
790 791 792 793 794 795 796 797 798 799 800 801
const MPPage = Page;
const MPComponent = Component;
const customizeRE = /:/g;
function customize(str) {
    return camelize(str.replace(customizeRE, '-'));
}
function initTriggerEvent(mpInstance) {
    const oldTriggerEvent = mpInstance.triggerEvent;
    mpInstance.triggerEvent = function (event, ...args) {
        return oldTriggerEvent.apply(mpInstance, [customize(event), ...args]);
    };
}
fxy060608's avatar
fxy060608 已提交
802 803 804 805 806
function initHook(name, options, isComponent) {
    if (isComponent) {
        // fix by Lxh 字节自定义组件Component构造器文档上写有created,但是实测只触发了lifetimes上的created
        options = options.lifetimes;
    }
fxy060608's avatar
fxy060608 已提交
807 808 809 810 811 812 813 814 815 816 817 818 819 820
    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) {
fxy060608's avatar
fxy060608 已提交
821
    initHook(ON_LOAD, options);
fxy060608's avatar
fxy060608 已提交
822 823 824
    return MPPage(options);
};
Component = function (options) {
fxy060608's avatar
fxy060608 已提交
825
    initHook('created', options, true);
fxy060608's avatar
fxy060608 已提交
826 827
    return MPComponent(options);
};
fxy060608's avatar
fxy060608 已提交
828

fxy060608's avatar
fxy060608 已提交
829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862
function provide(instance, key, value) {
    if (!instance) {
        if ((process.env.NODE_ENV !== 'production')) {
            console.warn(`provide() can only be used inside setup().`);
        }
    }
    else {
        let provides = instance.provides;
        // by default an instance inherits its parent's provides object
        // but when it needs to provide values of its own, it creates its
        // own provides object using parent provides object as prototype.
        // this way in `inject` we can simply look up injections from direct
        // parent and let the prototype chain do the work.
        const parentProvides = instance.parent && instance.parent.provides;
        if (parentProvides === provides) {
            provides = instance.provides = Object.create(parentProvides);
        }
        // TS doesn't allow symbol as index type
        provides[key] = value;
    }
}
function initProvide(instance) {
    const provideOptions = instance.$options.provide;
    if (!provideOptions) {
        return;
    }
    const provides = isFunction(provideOptions)
        ? provideOptions.call(instance)
        : provideOptions;
    const internalInstance = instance.$;
    for (const key in provides) {
        provide(internalInstance, key, provides[key]);
    }
}
863
function inject(instance, key, defaultValue, treatDefaultAsFactory = false) {
fxy060608's avatar
fxy060608 已提交
864
    if (instance) {
865 866 867 868 869 870 871
        // #2400
        // to support `app.use` plugins,
        // fallback to appContext's `provides` if the intance is at root
        const provides = instance.parent == null
            ? instance.vnode.appContext && instance.vnode.appContext.provides
            : instance.parent.provides;
        if (provides && key in provides) {
fxy060608's avatar
fxy060608 已提交
872 873 874 875
            // TS doesn't allow symbol as index type
            return provides[key];
        }
        else if (arguments.length > 1) {
876 877 878
            return treatDefaultAsFactory && isFunction(defaultValue)
                ? defaultValue()
                : defaultValue;
fxy060608's avatar
fxy060608 已提交
879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904
        }
        else if ((process.env.NODE_ENV !== 'production')) {
            console.warn(`injection "${String(key)}" not found.`);
        }
    }
    else if ((process.env.NODE_ENV !== 'production')) {
        console.warn(`inject() can only be used inside setup() or functional components.`);
    }
}
function initInjections(instance) {
    const injectOptions = instance.$options.inject;
    if (!injectOptions) {
        return;
    }
    const internalInstance = instance.$;
    const ctx = internalInstance.ctx;
    if (isArray(injectOptions)) {
        for (let i = 0; i < injectOptions.length; i++) {
            const key = injectOptions[i];
            ctx[key] = inject(internalInstance, key);
        }
    }
    else {
        for (const key in injectOptions) {
            const opt = injectOptions[key];
            if (isObject(opt)) {
905
                ctx[key] = inject(internalInstance, opt.from || key, opt.default, true /* treat default function as factory */);
fxy060608's avatar
fxy060608 已提交
906 907 908 909 910 911
            }
            else {
                ctx[key] = inject(internalInstance, opt);
            }
        }
    }
fxy060608's avatar
fxy060608 已提交
912 913
}

fxy060608's avatar
fxy060608 已提交
914 915
// 基础库 2.0 以上 attached 顺序错乱,按照 created 顺序强制纠正
const components = [];
916
function initLifetimes$1({ mocks, isPage, initRelation, vueOptions, }) {
fxy060608's avatar
fxy060608 已提交
917 918 919 920 921
    function created() {
        components.push(this);
    }
    function attached() {
        const properties = this.properties;
fxy060608's avatar
fxy060608 已提交
922
        initVueIds(properties.uI, this);
fxy060608's avatar
fxy060608 已提交
923 924 925 926 927 928 929 930 931
        const relationOptions = {
            vuePid: this._$vuePid,
        };
        // 初始化 vue 实例
        const mpInstance = this;
        const mpType = isPage(mpInstance) ? 'page' : 'component';
        if (mpType === 'page' && !mpInstance.route && mpInstance.__route__) {
            mpInstance.route = mpInstance.__route__;
        }
932 933 934 935 936 937 938
        // 字节跳动小程序 properties
        // 父组件在 attached 中 setData 设置了子组件的 props,在子组件的 attached 中,并不能立刻拿到
        // 此时子组件的 properties 中获取到的值,除了一部分初始化就有的值,只要在模板上绑定了,动态设置的 prop 的值均会根据类型返回,不会应用 prop 自己的默认值
        // 举例: easyinput 的 styles 属性,类型为 Object,`<easyinput :styles="styles"/>` 在 attached 中 styles 的值为 null
        // 目前 null 值会影响 render 函数执行,临时解决方案,调整 properties 中的 null 值为 undefined,让 Vue 来补充为默认值
        // 已知的其他隐患,当使用默认值时,可能组件行为不正确,比如 countdown 组件,默认值是0,导致直接就触发了 timeup 事件,这个应该是组件自身做处理?
        // 难道要等父组件首次 setData 完成后,再去执行子组件的初始化?
fxy060608's avatar
fxy060608 已提交
939 940 941 942 943 944 945
        fixProperties(properties);
        this.$vm = $createComponent({
            type: vueOptions,
            props: properties,
        }, {
            mpType,
            mpInstance,
fxy060608's avatar
fxy060608 已提交
946
            slots: properties.uS || {},
fxy060608's avatar
fxy060608 已提交
947 948 949 950 951 952 953 954 955 956 957 958 959
            parentComponent: relationOptions.parent && relationOptions.parent.$,
            onBeforeSetup(instance, options) {
                initRefs(instance, mpInstance);
                initMocks(instance, mpInstance, mocks);
                initComponentInstance(instance, options);
            },
        });
        // 处理父子关系
        initRelation(this, relationOptions);
    }
    function detached() {
        this.$vm && $destroyComponent(this.$vm);
    }
fxy060608's avatar
fxy060608 已提交
960
    return {
fxy060608's avatar
fxy060608 已提交
961
        created,
fxy060608's avatar
fxy060608 已提交
962
        attached() {
fxy060608's avatar
fxy060608 已提交
963
            this.__lifetimes_attached = function () {
fxy060608's avatar
fxy060608 已提交
964
                attached.call(this);
fxy060608's avatar
fxy060608 已提交
965
            };
fxy060608's avatar
fxy060608 已提交
966 967 968 969 970 971 972 973 974
            let component = this;
            while (component &&
                component.__lifetimes_attached &&
                components[0] &&
                component === components[0]) {
                components.shift();
                component.__lifetimes_attached();
                delete component.__lifetimes_attached;
                component = components[0];
fxy060608's avatar
fxy060608 已提交
975 976
            }
        },
fxy060608's avatar
fxy060608 已提交
977
        detached,
fxy060608's avatar
fxy060608 已提交
978
    };
fxy060608's avatar
fxy060608 已提交
979 980
}

fxy060608's avatar
fxy060608 已提交
981 982 983 984
const mocks = [
    '__route__',
    '__webviewId__',
    '__nodeId__',
985
    '__nodeid__' /* @Deprecated */,
fxy060608's avatar
fxy060608 已提交
986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000
];
function isPage(mpInstance) {
    return (mpInstance.__nodeId__ === 0 || mpInstance.__nodeid__ === 0);
}
const instances = Object.create(null);
function initRelation(mpInstance, detail) {
    // 头条 triggerEvent 后,接收事件时机特别晚,已经到了 ready 之后
    const nodeId = hasOwn(mpInstance, '__nodeId__')
        ? mpInstance.__nodeId__
        : mpInstance.__nodeid__;
    const webviewId = mpInstance.__webviewId__ + '';
    instances[webviewId + '_' + nodeId] = mpInstance.$vm;
    mpInstance.triggerEvent('__l', {
        vuePid: detail.vuePid,
        nodeId,
1001
        webviewId,
fxy060608's avatar
fxy060608 已提交
1002 1003
    });
}
1004
function handleLink({ detail: { vuePid, nodeId, webviewId }, }) {
fxy060608's avatar
fxy060608 已提交
1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025
    const vm = instances[webviewId + '_' + nodeId];
    if (!vm) {
        return;
    }
    let parentVm;
    if (vuePid) {
        parentVm = findVmByVueId(this.$vm, vuePid);
    }
    if (!parentVm) {
        parentVm = this.$vm;
    }
    vm.$.parent = parentVm.$;
    if (__VUE_OPTIONS_API__) {
        parentVm.$children.push(vm);
        const parent = parentVm.$;
        vm.$.provides = parent
            ? parent.provides
            : Object.create(parent.appContext.provides);
        initInjections(vm);
        initProvide(vm);
    }
1026
    vm.$callCreatedHook();
fxy060608's avatar
fxy060608 已提交
1027
    vm.$callHook('mounted');
fxy060608's avatar
fxy060608 已提交
1028
    vm.$callHook(ON_READY$1);
fxy060608's avatar
fxy060608 已提交
1029 1030 1031
}
function parse(componentOptions, { handleLink }) {
    componentOptions.methods.__l = handleLink;
fxy060608's avatar
fxy060608 已提交
1032 1033
}

fxy060608's avatar
fxy060608 已提交
1034
var parseComponentOptions = /*#__PURE__*/Object.freeze({
fxy060608's avatar
fxy060608 已提交
1035 1036 1037 1038 1039 1040 1041 1042
    __proto__: null,
    mocks: mocks,
    isPage: isPage,
    instances: instances,
    initRelation: initRelation,
    handleLink: handleLink,
    parse: parse,
    initLifetimes: initLifetimes$1
fxy060608's avatar
fxy060608 已提交
1043
});
fxy060608's avatar
fxy060608 已提交
1044

1045 1046
function initLifetimes(lifetimesOptions) {
    return extend(initLifetimes$1(lifetimesOptions), {
fxy060608's avatar
fxy060608 已提交
1047 1048
        ready() {
            if (this.$vm && lifetimesOptions.isPage(this)) {
fxy060608's avatar
fxy060608 已提交
1049 1050 1051
                if (this.pageinstance) {
                    this.__webviewId__ = this.pageinstance.__pageId__;
                }
1052
                this.$vm.$callCreatedHook();
fxy060608's avatar
fxy060608 已提交
1053
                this.$vm.$callHook('mounted');
fxy060608's avatar
fxy060608 已提交
1054
                this.$vm.$callHook(ON_READY$1);
fxy060608's avatar
fxy060608 已提交
1055 1056 1057 1058 1059 1060 1061 1062 1063 1064
            }
            else {
                this.is && console.warn(this.is + ' is not ready');
            }
        },
        detached() {
            this.$vm && $destroyComponent(this.$vm);
            // 清理
            const webviewId = this.__webviewId__;
            webviewId &&
1065
                Object.keys(instances).forEach((key) => {
fxy060608's avatar
fxy060608 已提交
1066 1067 1068 1069
                    if (key.indexOf(webviewId + '_') === 0) {
                        delete instances[key];
                    }
                });
1070
        },
fxy060608's avatar
fxy060608 已提交
1071
    });
fxy060608's avatar
fxy060608 已提交
1072 1073
}

fxy060608's avatar
fxy060608 已提交
1074
var parsePageOptions = /*#__PURE__*/Object.freeze({
fxy060608's avatar
fxy060608 已提交
1075 1076 1077 1078 1079 1080 1081
    __proto__: null,
    mocks: mocks,
    isPage: isPage,
    initRelation: initRelation,
    handleLink: handleLink,
    parse: parse,
    initLifetimes: initLifetimes
fxy060608's avatar
fxy060608 已提交
1082
});
fxy060608's avatar
fxy060608 已提交
1083

fxy060608's avatar
fxy060608 已提交
1084 1085
const createApp = initCreateApp();
const createPage = initCreatePage(parsePageOptions);
1086
const createComponent = initCreateComponent(parseComponentOptions);
fxy060608's avatar
fxy060608 已提交
1087
const createSubpackageApp = initCreateSubpackageApp();
fxy060608's avatar
fxy060608 已提交
1088
tt.EventChannel = EventChannel$1;
fxy060608's avatar
fxy060608 已提交
1089
tt.createApp = global.createApp = createApp;
1090
tt.createPage = createPage;
fxy060608's avatar
fxy060608 已提交
1091 1092
tt.createComponent = createComponent;
tt.createSubpackageApp = createSubpackageApp;
fxy060608's avatar
fxy060608 已提交
1093

fxy060608's avatar
fxy060608 已提交
1094
export { createApp, createComponent, createPage, createSubpackageApp };