uni.mp.esm.js 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964
  1. 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, ON_LAUNCH, ON_ERROR, ON_THEME_CHANGE, ON_PAGE_NOT_FOUND, ON_UNHANDLE_REJECTION, customizeEvent, addLeadingSlash, stringifyQuery, ON_BACK_PRESS } from '@dcloudio/uni-shared';
  2. import { isArray, isFunction, capitalize, hasOwn, extend, isPlainObject, isString } from '@vue/shared';
  3. import { ref, findComponentPropsData, toRaw, updateProps, hasQueueJob, invalidateJob, getExposeProxy, EMPTY_OBJ, isRef, setTemplateRef, devtoolsComponentAdded, pruneComponentPropsCache } from 'vue';
  4. import { normalizeLocale, LOCALE_EN } from '@dcloudio/uni-i18n';
  5. const MP_METHODS = [
  6. 'createSelectorQuery',
  7. 'createIntersectionObserver',
  8. 'selectAllComponents',
  9. 'selectComponent',
  10. ];
  11. function createEmitFn(oldEmit, ctx) {
  12. return function emit(event, ...args) {
  13. const scope = ctx.$scope;
  14. if (scope && event) {
  15. const detail = { __args__: args };
  16. {
  17. scope.triggerEvent(event, detail);
  18. }
  19. }
  20. {
  21. const props = scope.props;
  22. if (props && props[`on${capitalize(event)}`]) {
  23. return;
  24. }
  25. }
  26. return oldEmit.apply(this, [event, ...args]);
  27. };
  28. }
  29. function initBaseInstance(instance, options) {
  30. const ctx = instance.ctx;
  31. // mp
  32. ctx.mpType = options.mpType; // @deprecated
  33. ctx.$mpType = options.mpType;
  34. ctx.$mpPlatform = "mp-alipay";
  35. ctx.$scope = options.mpInstance;
  36. // TODO @deprecated
  37. ctx.$mp = {};
  38. if (__VUE_OPTIONS_API__) {
  39. ctx._self = {};
  40. }
  41. // slots
  42. instance.slots = {};
  43. if (isArray(options.slots) && options.slots.length) {
  44. options.slots.forEach((name) => {
  45. instance.slots[name] = true;
  46. });
  47. if (instance.slots[SLOT_DEFAULT_NAME]) {
  48. instance.slots.default = true;
  49. }
  50. }
  51. ctx.getOpenerEventChannel = function () {
  52. {
  53. if (my.canIUse('getOpenerEventChannel'))
  54. return options.mpInstance.getOpenerEventChannel();
  55. }
  56. if (!this.__eventChannel__) {
  57. this.__eventChannel__ = new EventChannel();
  58. }
  59. return this.__eventChannel__;
  60. };
  61. ctx.$hasHook = hasHook;
  62. ctx.$callHook = callHook;
  63. // $emit
  64. instance.emit = createEmitFn(instance.emit, ctx);
  65. }
  66. function initComponentInstance(instance, options) {
  67. initBaseInstance(instance, options);
  68. const ctx = instance.ctx;
  69. MP_METHODS.forEach((method) => {
  70. ctx[method] = function (...args) {
  71. const mpInstance = ctx.$scope;
  72. if (mpInstance && mpInstance[method]) {
  73. return mpInstance[method].apply(mpInstance, args);
  74. }
  75. {
  76. return my[method] && my[method].apply(my, args);
  77. }
  78. };
  79. });
  80. }
  81. function initMocks(instance, mpInstance, mocks) {
  82. const ctx = instance.ctx;
  83. mocks.forEach((mock) => {
  84. if (hasOwn(mpInstance, mock)) {
  85. instance[mock] = ctx[mock] = mpInstance[mock];
  86. }
  87. });
  88. }
  89. function hasHook(name) {
  90. const hooks = this.$[name];
  91. if (hooks && hooks.length) {
  92. return true;
  93. }
  94. return false;
  95. }
  96. function callHook(name, args) {
  97. if (name === 'mounted') {
  98. callHook.call(this, 'bm'); // beforeMount
  99. this.$.isMounted = true;
  100. name = 'm';
  101. }
  102. {
  103. if (name === 'onLoad' &&
  104. args &&
  105. args.__id__ &&
  106. isFunction(my.getEventChannel)) {
  107. this.__eventChannel__ = my.getEventChannel(args.__id__);
  108. delete args.__id__;
  109. }
  110. }
  111. const hooks = this.$[name];
  112. return hooks && invokeArrayFns(hooks, args);
  113. }
  114. const PAGE_INIT_HOOKS = [
  115. ON_LOAD,
  116. ON_SHOW,
  117. ON_HIDE,
  118. ON_UNLOAD,
  119. ON_RESIZE,
  120. ON_TAB_ITEM_TAP,
  121. ON_REACH_BOTTOM,
  122. ON_PULL_DOWN_REFRESH,
  123. ON_ADD_TO_FAVORITES,
  124. // 'onReady', // lifetimes.ready
  125. // 'onPageScroll', // 影响性能,开发者手动注册
  126. // 'onShareTimeline', // 右上角菜单,开发者手动注册
  127. // 'onShareAppMessage' // 右上角菜单,开发者手动注册
  128. ];
  129. function findHooks(vueOptions, hooks = new Set()) {
  130. if (vueOptions) {
  131. Object.keys(vueOptions).forEach((name) => {
  132. if (isUniLifecycleHook(name, vueOptions[name])) {
  133. hooks.add(name);
  134. }
  135. });
  136. if (__VUE_OPTIONS_API__) {
  137. const { extends: extendsOptions, mixins } = vueOptions;
  138. if (mixins) {
  139. mixins.forEach((mixin) => findHooks(mixin, hooks));
  140. }
  141. if (extendsOptions) {
  142. findHooks(extendsOptions, hooks);
  143. }
  144. }
  145. }
  146. return hooks;
  147. }
  148. function initHook(mpOptions, hook, excludes) {
  149. if (excludes.indexOf(hook) === -1 && !hasOwn(mpOptions, hook)) {
  150. mpOptions[hook] = function (args) {
  151. return this.$vm && this.$vm.$callHook(hook, args);
  152. };
  153. }
  154. }
  155. const EXCLUDE_HOOKS = [ON_READY];
  156. function initHooks(mpOptions, hooks, excludes = EXCLUDE_HOOKS) {
  157. hooks.forEach((hook) => initHook(mpOptions, hook, excludes));
  158. }
  159. function initUnknownHooks(mpOptions, vueOptions, excludes = EXCLUDE_HOOKS) {
  160. findHooks(vueOptions).forEach((hook) => initHook(mpOptions, hook, excludes));
  161. }
  162. function initRuntimeHooks(mpOptions, runtimeHooks) {
  163. if (!runtimeHooks) {
  164. return;
  165. }
  166. const hooks = Object.keys(MINI_PROGRAM_PAGE_RUNTIME_HOOKS);
  167. hooks.forEach((hook) => {
  168. if (runtimeHooks & MINI_PROGRAM_PAGE_RUNTIME_HOOKS[hook]) {
  169. initHook(mpOptions, hook, []);
  170. }
  171. });
  172. }
  173. const HOOKS = [
  174. ON_SHOW,
  175. ON_HIDE,
  176. ON_ERROR,
  177. ON_THEME_CHANGE,
  178. ON_PAGE_NOT_FOUND,
  179. ON_UNHANDLE_REJECTION,
  180. ];
  181. function parseApp(instance, parseAppOptions) {
  182. const internalInstance = instance.$;
  183. if (__VUE_PROD_DEVTOOLS__) {
  184. // 定制 App 的 $children
  185. Object.defineProperty(internalInstance.ctx, '$children', {
  186. get() {
  187. return getCurrentPages().map((page) => page.$vm);
  188. },
  189. });
  190. }
  191. const appOptions = {
  192. globalData: (instance.$options && instance.$options.globalData) || {},
  193. $vm: instance,
  194. onLaunch(options) {
  195. this.$vm = instance; // 飞书小程序可能会把 AppOptions 序列化,导致 $vm 对象部分属性丢失
  196. const ctx = internalInstance.ctx;
  197. if (this.$vm && ctx.$scope) {
  198. // 已经初始化过了,主要是为了百度,百度 onShow 在 onLaunch 之前
  199. return;
  200. }
  201. initBaseInstance(internalInstance, {
  202. mpType: 'app',
  203. mpInstance: this,
  204. slots: [],
  205. });
  206. ctx.globalData = this.globalData;
  207. instance.$callHook(ON_LAUNCH, options);
  208. },
  209. };
  210. const { onError } = internalInstance;
  211. if (onError) {
  212. internalInstance.appContext.config.errorHandler = (err) => {
  213. instance.$callHook(ON_ERROR, err);
  214. };
  215. }
  216. initLocale(instance);
  217. const vueOptions = instance.$.type;
  218. initHooks(appOptions, HOOKS);
  219. initUnknownHooks(appOptions, vueOptions);
  220. if (__VUE_OPTIONS_API__) {
  221. const methods = vueOptions.methods;
  222. methods && extend(appOptions, methods);
  223. }
  224. if (parseAppOptions) {
  225. parseAppOptions.parse(appOptions);
  226. }
  227. return appOptions;
  228. }
  229. function initCreateApp(parseAppOptions) {
  230. return function createApp(vm) {
  231. return App(parseApp(vm, parseAppOptions));
  232. };
  233. }
  234. function initCreateSubpackageApp(parseAppOptions) {
  235. return function createApp(vm) {
  236. const appOptions = parseApp(vm, parseAppOptions);
  237. const app = isFunction(getApp) &&
  238. getApp({
  239. allowDefault: true,
  240. });
  241. if (!app)
  242. return;
  243. vm.$.ctx.$scope = app;
  244. const globalData = app.globalData;
  245. if (globalData) {
  246. Object.keys(appOptions.globalData).forEach((name) => {
  247. if (!hasOwn(globalData, name)) {
  248. globalData[name] = appOptions.globalData[name];
  249. }
  250. });
  251. }
  252. Object.keys(appOptions).forEach((name) => {
  253. if (!hasOwn(app, name)) {
  254. app[name] = appOptions[name];
  255. }
  256. });
  257. initAppLifecycle(appOptions, vm);
  258. if (process.env.UNI_SUBPACKAGE) {
  259. (my.$subpackages || (my.$subpackages = {}))[process.env.UNI_SUBPACKAGE] = {
  260. $vm: vm,
  261. };
  262. }
  263. };
  264. }
  265. function initAppLifecycle(appOptions, vm) {
  266. if (isFunction(appOptions.onLaunch)) {
  267. const args = my.getLaunchOptionsSync && my.getLaunchOptionsSync();
  268. appOptions.onLaunch(args);
  269. }
  270. if (isFunction(appOptions.onShow) && my.onAppShow) {
  271. my.onAppShow((args) => {
  272. vm.$callHook('onShow', args);
  273. });
  274. }
  275. if (isFunction(appOptions.onHide) && my.onAppHide) {
  276. my.onAppHide((args) => {
  277. vm.$callHook('onHide', args);
  278. });
  279. }
  280. }
  281. function initLocale(appVm) {
  282. const locale = ref(normalizeLocale(my.getSystemInfoSync().language) || LOCALE_EN);
  283. Object.defineProperty(appVm, '$locale', {
  284. get() {
  285. return locale.value;
  286. },
  287. set(v) {
  288. locale.value = v;
  289. },
  290. });
  291. }
  292. function initVueIds(vueIds, mpInstance) {
  293. if (!vueIds) {
  294. return;
  295. }
  296. const ids = vueIds.split(',');
  297. const len = ids.length;
  298. if (len === 1) {
  299. mpInstance._$vueId = ids[0];
  300. }
  301. else if (len === 2) {
  302. mpInstance._$vueId = ids[0];
  303. mpInstance._$vuePid = ids[1];
  304. }
  305. }
  306. function initWxsCallMethods(methods, wxsCallMethods) {
  307. if (!isArray(wxsCallMethods)) {
  308. return;
  309. }
  310. wxsCallMethods.forEach((callMethod) => {
  311. methods[callMethod] = function (args) {
  312. return this.$vm[callMethod](args);
  313. };
  314. });
  315. }
  316. function findVmByVueId(instance, vuePid) {
  317. // 标准 vue3 中 没有 $children,定制了内核
  318. const $children = instance.$children;
  319. // 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200)
  320. for (let i = $children.length - 1; i >= 0; i--) {
  321. const childVm = $children[i];
  322. if (childVm.$scope._$vueId === vuePid) {
  323. return childVm;
  324. }
  325. }
  326. // 反向递归查找
  327. let parentVm;
  328. for (let i = $children.length - 1; i >= 0; i--) {
  329. parentVm = findVmByVueId($children[i], vuePid);
  330. if (parentVm) {
  331. return parentVm;
  332. }
  333. }
  334. }
  335. const builtInProps = [
  336. // 百度小程序,快手小程序自定义组件不支持绑定动态事件,动态dataset,故通过props传递事件信息
  337. // event-opts
  338. 'eO',
  339. // 组件 ref
  340. 'uR',
  341. // 组件 ref-in-for
  342. 'uRIF',
  343. // 组件 id
  344. 'uI',
  345. // 组件类型 m: 小程序组件
  346. 'uT',
  347. // 组件 props
  348. 'uP',
  349. // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
  350. 'uS',
  351. ];
  352. function initDefaultProps(options, isBehavior = false) {
  353. const properties = {};
  354. if (!isBehavior) {
  355. // 均不指定类型,避免微信小程序 property received type-uncompatible value 警告
  356. builtInProps.forEach((name) => {
  357. properties[name] = {
  358. type: null,
  359. value: '',
  360. };
  361. });
  362. // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
  363. properties.uS = {
  364. type: null,
  365. value: [],
  366. observer: function (newVal) {
  367. const $slots = Object.create(null);
  368. newVal &&
  369. newVal.forEach((slotName) => {
  370. $slots[slotName] = true;
  371. });
  372. this.setData({
  373. $slots,
  374. });
  375. },
  376. };
  377. }
  378. if (options.behaviors) {
  379. // wx://form-field
  380. if (options.behaviors.includes('my://form-field')) {
  381. if (!options.properties || !options.properties.name) {
  382. properties.name = {
  383. type: null,
  384. value: '',
  385. };
  386. }
  387. if (!options.properties || !options.properties.value) {
  388. properties.value = {
  389. type: null,
  390. value: '',
  391. };
  392. }
  393. }
  394. }
  395. return properties;
  396. }
  397. function initVirtualHostProps(options) {
  398. const properties = {};
  399. {
  400. {
  401. properties.virtualHostStyle = {
  402. type: null,
  403. value: '',
  404. };
  405. properties.virtualHostClass = {
  406. type: null,
  407. value: '',
  408. };
  409. }
  410. }
  411. return properties;
  412. }
  413. /**
  414. *
  415. * @param mpComponentOptions
  416. * @param isBehavior
  417. */
  418. function initProps(mpComponentOptions) {
  419. if (!mpComponentOptions.properties) {
  420. mpComponentOptions.properties = {};
  421. }
  422. extend(mpComponentOptions.properties, initDefaultProps(mpComponentOptions), initVirtualHostProps(mpComponentOptions.options));
  423. }
  424. function findPropsData(properties, isPage) {
  425. return ((isPage
  426. ? findPagePropsData(properties)
  427. : findComponentPropsData(properties.uP)) || {});
  428. }
  429. function findPagePropsData(properties) {
  430. const propsData = {};
  431. if (isPlainObject(properties)) {
  432. Object.keys(properties).forEach((name) => {
  433. if (builtInProps.indexOf(name) === -1) {
  434. propsData[name] = properties[name];
  435. }
  436. });
  437. }
  438. return propsData;
  439. }
  440. function initData(_) {
  441. return {};
  442. }
  443. function updateMiniProgramComponentProperties(up, mpInstance) {
  444. const prevProps = mpInstance.props
  445. ;
  446. const nextProps = findComponentPropsData(up) || {};
  447. if (hasPropsChanged(prevProps, nextProps, false)) {
  448. mpInstance.setData(nextProps);
  449. }
  450. }
  451. function updateComponentProps(up, instance) {
  452. const prevProps = toRaw(instance.props);
  453. const nextProps = findComponentPropsData(up) || {};
  454. if (hasPropsChanged(prevProps, nextProps)) {
  455. updateProps(instance, nextProps, prevProps, false);
  456. if (hasQueueJob(instance.update)) {
  457. invalidateJob(instance.update);
  458. }
  459. {
  460. instance.update();
  461. }
  462. }
  463. }
  464. function hasPropsChanged(prevProps, nextProps, checkLen = true) {
  465. const nextKeys = Object.keys(nextProps);
  466. if (checkLen && nextKeys.length !== Object.keys(prevProps).length) {
  467. return true;
  468. }
  469. for (let i = 0; i < nextKeys.length; i++) {
  470. const key = nextKeys[i];
  471. if (nextProps[key] !== prevProps[key]) {
  472. return true;
  473. }
  474. }
  475. return false;
  476. }
  477. function initBehaviors(vueOptions) {
  478. const vueBehaviors = vueOptions.behaviors;
  479. let vueProps = vueOptions.props;
  480. if (!vueProps) {
  481. vueOptions.props = vueProps = [];
  482. }
  483. const behaviors = [];
  484. if (isArray(vueBehaviors)) {
  485. vueBehaviors.forEach((behavior) => {
  486. behaviors.push(behavior.replace('uni://', 'my://'));
  487. if (behavior === 'uni://form-field') {
  488. if (isArray(vueProps)) {
  489. vueProps.push('name');
  490. vueProps.push('modelValue');
  491. }
  492. else {
  493. vueProps.name = {
  494. type: String,
  495. default: '',
  496. };
  497. vueProps.modelValue = {
  498. type: [String, Number, Boolean, Array, Object, Date],
  499. default: '',
  500. };
  501. }
  502. }
  503. });
  504. }
  505. return behaviors;
  506. }
  507. let $createComponentFn;
  508. let $destroyComponentFn;
  509. function getAppVm() {
  510. if (process.env.UNI_MP_PLUGIN) {
  511. return my.$vm;
  512. }
  513. if (process.env.UNI_SUBPACKAGE) {
  514. return my.$subpackages[process.env.UNI_SUBPACKAGE].$vm;
  515. }
  516. return getApp().$vm;
  517. }
  518. function $createComponent(initialVNode, options) {
  519. if (!$createComponentFn) {
  520. $createComponentFn = getAppVm().$createComponent;
  521. }
  522. const proxy = $createComponentFn(initialVNode, options);
  523. return getExposeProxy(proxy.$) || proxy;
  524. }
  525. function $destroyComponent(instance) {
  526. if (!$destroyComponentFn) {
  527. $destroyComponentFn = getAppVm().$destroyComponent;
  528. }
  529. return $destroyComponentFn(instance);
  530. }
  531. function initCreatePluginApp(parseAppOptions) {
  532. return function createApp(vm) {
  533. initAppLifecycle(parseApp(vm, parseAppOptions), vm);
  534. if (process.env.UNI_MP_PLUGIN) {
  535. my.$vm = vm;
  536. }
  537. };
  538. }
  539. function handleLink$1(event) {
  540. // detail 是微信,value 是百度(dipatch)
  541. const detail = (event.detail ||
  542. event.value);
  543. const vuePid = detail.vuePid;
  544. let parentVm;
  545. if (vuePid) {
  546. parentVm = findVmByVueId(this.$vm, vuePid);
  547. }
  548. if (!parentVm) {
  549. parentVm = this.$vm;
  550. }
  551. detail.parent = parentVm;
  552. }
  553. const isComponent2 = my.canIUse('component2');
  554. const mocks = ['$id'];
  555. function initRelation(mpInstance, detail) {
  556. // onVueInit
  557. mpInstance.props.onVI(detail);
  558. }
  559. function initSpecialMethods(mpInstance) {
  560. if (!mpInstance.$vm) {
  561. return;
  562. }
  563. let path = mpInstance.is || mpInstance.route;
  564. if (!path) {
  565. return;
  566. }
  567. if (path.indexOf('/') === 0) {
  568. path = path.slice(1);
  569. }
  570. const specialMethods = my.specialMethods && my.specialMethods[path];
  571. if (specialMethods) {
  572. specialMethods.forEach((method) => {
  573. if (isFunction(mpInstance.$vm[method])) {
  574. mpInstance[method] = function (event) {
  575. if (hasOwn(event, 'markerId')) {
  576. event.detail = typeof event.detail === 'object' ? event.detail : {};
  577. event.detail.markerId = event.markerId;
  578. }
  579. // TODO normalizeEvent
  580. mpInstance.$vm[method](event);
  581. };
  582. }
  583. });
  584. }
  585. }
  586. function initChildVues(mpInstance) {
  587. // 此时需保证当前 mpInstance 已经存在 $vm
  588. if (!mpInstance.$vm) {
  589. return;
  590. }
  591. const childVues = mpInstance._$childVues;
  592. if (childVues) {
  593. childVues.forEach((relationOptions) => {
  594. // 父子关系
  595. handleLink$1.call(mpInstance, {
  596. detail: relationOptions,
  597. });
  598. const { mpInstance: childMPInstance, createComponent } = relationOptions;
  599. childMPInstance.$vm = createComponent(relationOptions.parent);
  600. initSpecialMethods(childMPInstance);
  601. if (relationOptions.parent) {
  602. handleRef.call(relationOptions.parent.$scope, childMPInstance);
  603. }
  604. initChildVues(childMPInstance);
  605. childMPInstance.$vm.$callHook('mounted');
  606. childMPInstance.$vm.$callHook(ON_READY);
  607. });
  608. }
  609. delete mpInstance._$childVues;
  610. }
  611. function handleRef(ref) {
  612. if (!ref) {
  613. return;
  614. }
  615. const refName = ref.props.uR; // data-ref
  616. const refInForName = ref.props.uRIF; // data-ref-in-for
  617. if (!refName && !refInForName) {
  618. return;
  619. }
  620. const instance = this.$vm.$;
  621. const refs = instance.refs === EMPTY_OBJ ? (instance.refs = {}) : instance.refs;
  622. const { setupState } = instance;
  623. const refValue = ref.$vm;
  624. if (refName) {
  625. if (isString(refName)) {
  626. refs[refName] = refValue;
  627. if (hasOwn(setupState, refName)) {
  628. setupState[refName] = refValue;
  629. }
  630. }
  631. else {
  632. setRef(refName, refValue, refs, setupState);
  633. }
  634. }
  635. else if (refInForName) {
  636. if (isString(refInForName)) {
  637. (refs[refInForName] || (refs[refInForName] = [])).push(refValue);
  638. }
  639. else {
  640. setRef(refInForName, refValue, refs, setupState);
  641. }
  642. }
  643. }
  644. function isTemplateRef(opts) {
  645. return !!(opts && opts.r);
  646. }
  647. function setRef(ref, refValue, refs, setupState) {
  648. if (isRef(ref)) {
  649. ref.value = refValue;
  650. }
  651. else if (isFunction(ref)) {
  652. const templateRef = ref(refValue, refs);
  653. if (isTemplateRef(templateRef)) {
  654. setTemplateRef(templateRef, refValue, setupState);
  655. }
  656. }
  657. }
  658. function triggerEvent(type, detail) {
  659. const handler = this.props[customizeEvent('on-' + type)];
  660. if (!handler) {
  661. return;
  662. }
  663. const target = {
  664. dataset: {},
  665. };
  666. handler({
  667. type: customizeEvent(type),
  668. target,
  669. currentTarget: target,
  670. detail,
  671. });
  672. }
  673. // const IGNORES = ['$slots', '$scopedSlots']
  674. function initPropsObserver(componentOptions) {
  675. const observe = function observe(props) {
  676. const nextProps = isComponent2 ? props : this.props;
  677. const up = nextProps.uP;
  678. if (!up) {
  679. return;
  680. }
  681. if (this.$vm) {
  682. updateComponentProps(up, this.$vm.$);
  683. }
  684. else if (this.props.uT === 'm') {
  685. // 小程序组件
  686. updateMiniProgramComponentProperties(up, this);
  687. }
  688. };
  689. if (isComponent2) {
  690. componentOptions.deriveDataFromProps = observe;
  691. }
  692. else {
  693. componentOptions.didUpdate = observe;
  694. }
  695. }
  696. const handleLink = (function () {
  697. if (isComponent2) {
  698. return function handleLink(detail) {
  699. return handleLink$1.call(this, {
  700. detail,
  701. });
  702. };
  703. }
  704. return function handleLink(detail) {
  705. if (this.$vm && this.$vm.$.isMounted) {
  706. // 父已初始化
  707. return handleLink$1.call(this, {
  708. detail,
  709. });
  710. }
  711. (this._$childVues || (this._$childVues = [])).unshift(detail);
  712. };
  713. })();
  714. function createVueComponent(mpType, mpInstance, vueOptions, parent) {
  715. return $createComponent({
  716. type: vueOptions,
  717. props: findPropsData(mpInstance.props, mpType === 'page'),
  718. }, {
  719. mpType,
  720. mpInstance,
  721. slots: mpInstance.props.uS || {},
  722. parentComponent: parent && parent.$,
  723. onBeforeSetup(instance, options) {
  724. initMocks(instance, mpInstance, mocks);
  725. initComponentInstance(instance, options);
  726. },
  727. });
  728. }
  729. const MPComponent = Component;
  730. Component = function (options) {
  731. // 小程序组件
  732. const isVueComponent = options.props && typeof options.props.uP !== 'undefined';
  733. if (!isVueComponent) {
  734. initPropsObserver(options);
  735. }
  736. return MPComponent(options);
  737. };
  738. function onAliAuthError(method, $event) {
  739. $event.type = 'getphonenumber';
  740. $event.detail.errMsg =
  741. 'getPhoneNumber:fail Error: ' + $event.detail.errorMessage;
  742. method($event);
  743. }
  744. function onAliGetAuthorize(method, $event) {
  745. my.getPhoneNumber({
  746. success: (res) => {
  747. $event.type = 'getphonenumber';
  748. const response = JSON.parse(res.response);
  749. $event.detail.errMsg = 'getPhoneNumber:ok';
  750. $event.detail.encryptedData = response.response;
  751. $event.detail.sign = response.sign;
  752. method($event);
  753. },
  754. fail: (res) => {
  755. $event.type = 'getphonenumber';
  756. $event.detail.errMsg = 'getPhoneNumber:fail Error: ' + JSON.stringify(res);
  757. method($event);
  758. },
  759. });
  760. }
  761. function parse(appOptions) {
  762. const oldOnLaunch = appOptions.onLaunch;
  763. appOptions.onLaunch = function onLaunch(options) {
  764. oldOnLaunch.call(this, options);
  765. if (!this.$vm) {
  766. return;
  767. }
  768. const globalProperties = this.$vm.$app.config.globalProperties;
  769. if (!globalProperties.$onAliAuthError) {
  770. globalProperties.$onAliAuthError = onAliAuthError;
  771. globalProperties.$onAliGetAuthorize = onAliGetAuthorize;
  772. }
  773. };
  774. }
  775. var parseAppOptions = /*#__PURE__*/Object.freeze({
  776. __proto__: null,
  777. parse: parse
  778. });
  779. function initCreatePage() {
  780. return function createPage(vueOptions) {
  781. vueOptions = vueOptions.default || vueOptions;
  782. const pageOptions = {
  783. onLoad(query) {
  784. this.options = query;
  785. this.$page = {
  786. fullPath: addLeadingSlash(this.route + stringifyQuery(query)),
  787. };
  788. // 初始化 vue 实例
  789. this.props = query;
  790. this.$vm = createVueComponent('page', this, vueOptions);
  791. initSpecialMethods(this);
  792. this.$vm.$callHook(ON_LOAD, query);
  793. },
  794. onShow() {
  795. if (__VUE_PROD_DEVTOOLS__) {
  796. devtoolsComponentAdded(this.$vm.$);
  797. }
  798. this.$vm.$callHook(ON_SHOW);
  799. },
  800. onReady() {
  801. initChildVues(this);
  802. this.$vm.$callHook('mounted');
  803. this.$vm.$callHook(ON_READY);
  804. },
  805. onUnload() {
  806. if (this.$vm) {
  807. this.$vm.$callHook(ON_UNLOAD);
  808. $destroyComponent(this.$vm);
  809. }
  810. },
  811. events: {
  812. // 支付宝小程序有些页面事件只能放在events下
  813. onBack() {
  814. this.$vm.$callHook(ON_BACK_PRESS);
  815. },
  816. onKeyboardHeight: ((res) => {
  817. my.$emit('uni:keyboardHeightChange', res);
  818. }),
  819. },
  820. __r: handleRef,
  821. __l: handleLink,
  822. };
  823. if (isPlainObject(vueOptions.events)) {
  824. extend(pageOptions.events, vueOptions.events);
  825. }
  826. if (__VUE_OPTIONS_API__) {
  827. pageOptions.data = initData();
  828. }
  829. initHooks(pageOptions, PAGE_INIT_HOOKS);
  830. initUnknownHooks(pageOptions, vueOptions);
  831. initRuntimeHooks(pageOptions, vueOptions.__runtimeHooks);
  832. initWxsCallMethods(pageOptions, vueOptions.wxsCallMethods);
  833. return Page(pageOptions);
  834. };
  835. }
  836. // @ts-ignore
  837. function initComponentProps(_rawProps) {
  838. const propertiesOptions = {
  839. properties: {},
  840. };
  841. initProps(propertiesOptions);
  842. const properties = propertiesOptions.properties;
  843. const props = {
  844. // onVueInit
  845. onVI: function () { },
  846. };
  847. Object.keys(properties).forEach((key) => {
  848. // vueSlots
  849. if (key !== 'uS') {
  850. props[key] = properties[key].value;
  851. }
  852. });
  853. return props;
  854. }
  855. function initVm(mpInstance, createComponent) {
  856. if (mpInstance.$vm) {
  857. return;
  858. }
  859. const properties = mpInstance.props;
  860. initVueIds(properties.uI, mpInstance);
  861. const relationOptions = {
  862. vuePid: mpInstance._$vuePid,
  863. mpInstance,
  864. createComponent,
  865. };
  866. if (isComponent2) {
  867. // 处理父子关系
  868. initRelation(mpInstance, relationOptions);
  869. // 初始化 vue 实例
  870. mpInstance.$vm = createComponent(relationOptions.parent);
  871. }
  872. else {
  873. // 处理父子关系
  874. initRelation(mpInstance, relationOptions);
  875. if (relationOptions.parent) {
  876. // 父组件已经初始化,直接初始化子,否则放到父组件的 didMount 中处理
  877. // 初始化 vue 实例
  878. mpInstance.$vm = createComponent(relationOptions.parent);
  879. handleRef.call(relationOptions.parent.$scope, mpInstance);
  880. initChildVues(mpInstance);
  881. mpInstance.$vm.$callHook('mounted');
  882. }
  883. }
  884. }
  885. function initCreateComponent() {
  886. return function createComponent(vueOptions) {
  887. vueOptions = vueOptions.default || vueOptions;
  888. const mpComponentOptions = {
  889. props: initComponentProps(vueOptions.props),
  890. didMount() {
  891. const createComponent = (parent) => {
  892. return createVueComponent('component', this, vueOptions, parent);
  893. };
  894. if (my.dd) {
  895. // 钉钉小程序底层基础库有 bug,组件嵌套使用时,在 didMount 中无法及时调用 props 中的方法
  896. setTimeout(() => {
  897. initVm(this, createComponent);
  898. }, 4);
  899. }
  900. else {
  901. initVm(this, createComponent);
  902. }
  903. initSpecialMethods(this);
  904. if (isComponent2) {
  905. this.$vm.$callHook('mounted');
  906. }
  907. },
  908. didUnmount() {
  909. if (this.$vm) {
  910. pruneComponentPropsCache(this.$vm.$.uid);
  911. $destroyComponent(this.$vm);
  912. }
  913. },
  914. methods: {
  915. __r: handleRef,
  916. __l: handleLink,
  917. triggerEvent,
  918. },
  919. };
  920. if (__VUE_OPTIONS_API__) {
  921. mpComponentOptions.data = initData();
  922. mpComponentOptions.mixins = initBehaviors(vueOptions);
  923. }
  924. if (isComponent2) {
  925. mpComponentOptions.onInit = function onInit() {
  926. initVm(this, (parent) => {
  927. return createVueComponent('component', this, vueOptions, parent);
  928. });
  929. };
  930. }
  931. initPropsObserver(mpComponentOptions);
  932. initWxsCallMethods(mpComponentOptions.methods, vueOptions.wxsCallMethods);
  933. return Component(mpComponentOptions);
  934. };
  935. }
  936. const createApp = initCreateApp(parseAppOptions);
  937. const createPage = initCreatePage();
  938. const createComponent = initCreateComponent();
  939. const createPluginApp = initCreatePluginApp(parseAppOptions);
  940. const createSubpackageApp = initCreateSubpackageApp(parseAppOptions);
  941. my.EventChannel = EventChannel;
  942. my.createApp = createApp;
  943. my.createPage = createPage;
  944. my.createComponent = createComponent;
  945. my.createPluginApp = createPluginApp;
  946. my.createSubpackageApp = createSubpackageApp;
  947. export { createApp, createComponent, createPage, createPluginApp, createSubpackageApp };