提交 30362f36 编写于 作者: fxy060608's avatar fxy060608

feat(mp): EventChannel

上级 062fc810
import { isArray, hasOwn, isString, isPlainObject, isObject, capitalize, toRawType, makeMap, isPromise, isFunction, extend } from '@vue/shared';
const eventChannels = {};
const eventChannelStack = [];
let id = 0;
function initEventChannel(events, cache = true) {
id++;
const eventChannel = new my.EventChannel(id, events);
if (cache) {
eventChannels[id] = eventChannel;
eventChannelStack.push(eventChannel);
}
return eventChannel;
}
function getEventChannel(id) {
if (id) {
const eventChannel = eventChannels[id];
delete eventChannels[id];
return eventChannel;
}
return eventChannelStack.shift();
}
const navigateTo = {
args(fromArgs) {
const id = initEventChannel(fromArgs.events).id;
if (fromArgs.url) {
fromArgs.url =
fromArgs.url +
(fromArgs.url.indexOf('?') === -1 ? '?' : '&') +
'__id__=' +
id;
}
},
returnValue(fromRes) {
fromRes.eventChannel = getEventChannel();
},
};
function getBaseSystemInfo() {
return my.getSystemInfoSync()
}
......@@ -623,7 +659,8 @@ function addSafeAreaInsets(fromRes, toRes) {
bottom: fromRes.windowHeight - safeArea.bottom,
};
}
}
}
const redirectTo = {};
const getProvider = initGetProvider({
......@@ -1212,7 +1249,8 @@ var protocols = /*#__PURE__*/Object.freeze({
saveImageToPhotosAlbum: saveImageToPhotosAlbum,
saveVideoToPhotosAlbum: saveVideoToPhotosAlbum,
chooseAddress: chooseAddress,
redirectTo: redirectTo
redirectTo: redirectTo,
navigateTo: navigateTo
});
var index = initUni(shims, protocols);
......
import { hasOwn, isArray, toNumber, isPlainObject, isObject, capitalize, isFunction, extend, NOOP, EMPTY_OBJ, camelize } from '@vue/shared';
import { isPlainObject, hasOwn, isArray, toNumber, isObject, capitalize, isFunction, extend, NOOP, EMPTY_OBJ, camelize } from '@vue/shared';
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}` : '';
}
const invokeArrayFns = (fns, arg) => {
let ret;
for (let i = 0; i < fns.length; i++) {
ret = fns[i](arg);
}
return ret;
};
// 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_BACK_PRESS = 'onBackPress';
const ON_TAB_ITEM_TAP = 'onTabItemTap';
const ON_REACH_BOTTOM = 'onReachBottom';
const ON_PULL_DOWN_REFRESH = 'onPullDownRefresh';
const ON_ADD_TO_FAVORITES = 'onAddToFavorites';
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();
}
function setModel(target, key, value, modifiers) {
if (isArray(modifiers)) {
......@@ -88,6 +209,14 @@ function initBaseInstance(instance, options) {
},
});
}
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);
}
......@@ -120,47 +249,22 @@ function initMocks(instance, mpInstance, mocks) {
ctx[mock] = mpInstance[mock];
}
});
}
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}` : '';
}
// 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_BACK_PRESS = 'onBackPress';
const ON_TAB_ITEM_TAP = 'onTabItemTap';
const ON_REACH_BOTTOM = 'onReachBottom';
const ON_PULL_DOWN_REFRESH = 'onPullDownRefresh';
const ON_ADD_TO_FAVORITES = 'onAddToFavorites';
function hasHook(name) {
const hooks = this.$[name];
if (hooks && hooks.length) {
return true;
}
return false;
}
function callHook(name, args) {
if (name === 'onLoad' && args && args.__id__) {
this.__eventChannel__ = getEventChannel(args.__id__);
delete args.__id__;
}
const hooks = this.$[name];
return hooks && invokeArrayFns(hooks, args);
}
const PAGE_HOOKS = [
ON_LOAD,
......@@ -282,7 +386,7 @@ function initWxsCallMethods(methods, wxsCallMethods) {
});
}
function findVmByVueId(instance, vuePid) {
// TODO vue3 中 没有 $children
// 标准 vue3 中 没有 $children,定制了内核
const $children = instance.$children;
// 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200)
for (let i = $children.length - 1; i >= 0; i--) {
......@@ -757,8 +861,8 @@ function parse(appOptions) {
}
var parseAppOptions = /*#__PURE__*/Object.freeze({
__proto__: null,
parse: parse
__proto__: null,
parse: parse
});
function handleLink$1(event) {
......@@ -1128,6 +1232,7 @@ function createComponent$1(vueOptions) {
}
const createApp = initCreateApp(parseAppOptions);
my.EventChannel = EventChannel;
my.createApp = createApp;
my.createPage = createPage;
my.createComponent = createComponent;
......
......@@ -2,7 +2,7 @@ import { isPlainObject, isArray } from '@vue/shared'
import { addSafeAreaInsets } from '@dcloudio/uni-mp-core'
export { redirectTo } from '@dcloudio/uni-mp-core'
export { redirectTo, navigateTo } from '@dcloudio/uni-mp-core'
function handleNetworkInfo(
fromRes: my.IGetNetworkTypeSuccessResult,
......@@ -202,7 +202,7 @@ export const compressImage = {
},
returnValue(
fromRes: my.ICompressImageSuccessResult,
toRes: UniApp.CompressImageSuccessData
toRes: UniApp.CompressVideoSuccessData
) {
const apFilePaths = fromRes.apFilePaths
if (apFilePaths && apFilePaths.length) {
......@@ -234,7 +234,7 @@ export const previewImage = {
const currentIndex = Number(fromArgs.current)
if (isNaN(currentIndex)) {
if (fromArgs.current && isArray(fromArgs.urls)) {
const index = fromArgs.urls.indexOf(fromArgs.current)
const index = fromArgs.urls.indexOf(fromArgs.current as string)
toArgs.current = ~index ? index : 0
}
} else {
......
import { EventChannel } from '@dcloudio/uni-shared'
import { initCreateApp } from '@dcloudio/uni-mp-core'
import * as parseAppOptions from './parseAppOptions'
......@@ -6,6 +8,7 @@ export { createPage } from './createPage'
export { createComponent } from './createComponent'
export const createApp = initCreateApp(parseAppOptions)
;(my as any).EventChannel = EventChannel
;(my as any).createApp = createApp
;(my as any).createPage = createPage
;(my as any).createComponent = createComponent
import { isArray, hasOwn, isString, isPlainObject, isObject, capitalize, toRawType, makeMap, isPromise, isFunction, extend } from '@vue/shared';
const eventChannels = {};
const eventChannelStack = [];
let id = 0;
function initEventChannel(events, cache = true) {
id++;
const eventChannel = new swan.EventChannel(id, events);
if (cache) {
eventChannels[id] = eventChannel;
eventChannelStack.push(eventChannel);
}
return eventChannel;
}
function getEventChannel(id) {
if (id) {
const eventChannel = eventChannels[id];
delete eventChannels[id];
return eventChannel;
}
return eventChannelStack.shift();
}
const navigateTo = {
args(fromArgs) {
const id = initEventChannel(fromArgs.events).id;
if (fromArgs.url) {
fromArgs.url =
fromArgs.url +
(fromArgs.url.indexOf('?') === -1 ? '?' : '&') +
'__id__=' +
id;
}
},
returnValue(fromRes) {
fromRes.eventChannel = getEventChannel();
},
};
function getBaseSystemInfo() {
return swan.getSystemInfoSync()
}
......@@ -613,6 +649,26 @@ function initGetProvider(providers) {
};
}
function addSafeAreaInsets(fromRes, toRes) {
if (fromRes.safeArea) {
const safeArea = fromRes.safeArea;
toRes.safeAreaInsets = {
top: safeArea.top,
left: safeArea.left,
right: fromRes.windowWidth - safeArea.right,
bottom: fromRes.windowHeight - safeArea.bottom,
};
}
}
const getSystemInfo = {
returnValue: addSafeAreaInsets,
};
const getSystemInfoSync = getSystemInfo;
const redirectTo = {};
const previewImage = {
args(fromArgs, toArgs) {
let currentIndex = parseInt(fromArgs.current);
......@@ -645,23 +701,7 @@ const previewImage = {
loop: false,
};
},
};
function addSafeAreaInsets(fromRes, toRes) {
if (fromRes.safeArea) {
const safeArea = fromRes.safeArea;
toRes.safeAreaInsets = {
top: safeArea.top,
left: safeArea.left,
right: fromRes.windowWidth - safeArea.right,
bottom: fromRes.windowHeight - safeArea.bottom,
};
}
}
const getSystemInfo = {
returnValue: addSafeAreaInsets,
};
const getSystemInfoSync = getSystemInfo;
const redirectTo = {};
};
const getProvider = initGetProvider({
oauth: ['baidu'],
......@@ -777,6 +817,7 @@ var protocols = /*#__PURE__*/Object.freeze({
showShareMenu: showShareMenu,
getAccountInfoSync: getAccountInfoSync,
redirectTo: redirectTo,
navigateTo: navigateTo,
previewImage: previewImage,
getSystemInfo: getSystemInfo,
getSystemInfoSync: getSystemInfoSync
......
import { isArray, hasOwn, toNumber, isPlainObject, isObject, isFunction, extend, NOOP, camelize } from '@vue/shared';
import { isPlainObject, isArray, hasOwn, toNumber, isObject, isFunction, extend, NOOP, camelize } from '@vue/shared';
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}` : '';
}
const invokeArrayFns = (fns, arg) => {
let ret;
for (let i = 0; i < fns.length; i++) {
ret = fns[i](arg);
}
return ret;
};
// 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';
const ON_ADD_TO_FAVORITES = 'onAddToFavorites';
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();
}
function setModel(target, key, value, modifiers) {
if (isArray(modifiers)) {
......@@ -82,6 +202,14 @@ function initBaseInstance(instance, options) {
});
}
}
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);
}
......@@ -111,46 +239,22 @@ function initMocks(instance, mpInstance, mocks) {
ctx[mock] = mpInstance[mock];
}
});
}
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}` : '';
}
// 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';
const ON_ADD_TO_FAVORITES = 'onAddToFavorites';
function hasHook(name) {
const hooks = this.$[name];
if (hooks && hooks.length) {
return true;
}
return false;
}
function callHook(name, args) {
if (name === 'onLoad' && args && args.__id__) {
this.__eventChannel__ = getEventChannel(args.__id__);
delete args.__id__;
}
const hooks = this.$[name];
return hooks && invokeArrayFns(hooks, args);
}
const PAGE_HOOKS = [
ON_LOAD,
......@@ -304,7 +408,7 @@ function initRefs(instance, mpInstance) {
});
}
function findVmByVueId(instance, vuePid) {
// TODO vue3 中 没有 $children
// 标准 vue3 中 没有 $children,定制了内核
const $children = instance.$children;
// 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200)
for (let i = $children.length - 1; i >= 0; i--) {
......@@ -882,8 +986,8 @@ function parse$2(appOptions) {
}
var parseAppOptions = /*#__PURE__*/Object.freeze({
__proto__: null,
parse: parse$2
__proto__: null,
parse: parse$2
});
function initLifetimes({ mocks, isPage, initRelation, vueOptions, }) {
......@@ -988,13 +1092,13 @@ function parse$1(componentOptions) {
}
var parseComponentOptions = /*#__PURE__*/Object.freeze({
__proto__: null,
mocks: mocks,
isPage: isPage,
initRelation: initRelation,
parse: parse$1,
handleLink: handleLink,
initLifetimes: initLifetimes
__proto__: null,
mocks: mocks,
isPage: isPage,
initRelation: initRelation,
parse: parse$1,
handleLink: handleLink,
initLifetimes: initLifetimes
});
function parse(pageOptions) {
......@@ -1020,18 +1124,19 @@ function parse(pageOptions) {
}
var parsePageOptions = /*#__PURE__*/Object.freeze({
__proto__: null,
parse: parse,
handleLink: handleLink,
initLifetimes: initLifetimes,
mocks: mocks,
isPage: isPage,
initRelation: initRelation
__proto__: null,
parse: parse,
handleLink: handleLink,
initLifetimes: initLifetimes,
mocks: mocks,
isPage: isPage,
initRelation: initRelation
});
const createApp = initCreateApp(parseAppOptions);
const createPage = initCreatePage(parsePageOptions);
const createComponent = initCreateComponent(parseComponentOptions);
swan.EventChannel = EventChannel;
swan.createApp = createApp;
swan.createPage = createPage;
swan.createComponent = createComponent;
......
export {
redirectTo,
navigateTo,
previewImage,
getSystemInfo,
getSystemInfoSync,
......
import { EventChannel } from '@dcloudio/uni-shared'
import {
initCreateApp,
initCreatePage,
......@@ -13,6 +14,7 @@ import * as parseComponentOptions from './parseComponentOptions'
export const createApp = initCreateApp(parseAppOptions)
export const createPage = initCreatePage(parsePageOptions)
export const createComponent = initCreateComponent(parseComponentOptions)
;(swan as any).EventChannel = EventChannel
;(swan as any).createApp = createApp
;(swan as any).createPage = createPage
;(swan as any).createComponent = createComponent
import { hasOwn } from '@vue/shared'
// 直接引用具体文件,避免引入其他需要额外配置的信息,比如@dcloudio/uni-platform
import { upx2px } from '@dcloudio/uni-api/src/service/base/upx2px'
import {
addInterceptor,
......
export function addSafeAreaInsets(
fromRes: any,
toRes: UniApp.GetSystemInfoResult
) {
if (fromRes.safeArea) {
const safeArea = fromRes.safeArea
toRes.safeAreaInsets = {
top: safeArea.top,
left: safeArea.left,
right: fromRes.windowWidth - safeArea.right,
bottom: fromRes.windowHeight - safeArea.bottom,
}
}
}
import { addSafeAreaInsets } from './addSafeAreaInsets'
import { MPProtocol } from './types'
export const getSystemInfo: MPProtocol = {
returnValue: addSafeAreaInsets,
}
import { getSystemInfo } from './getSystemInfo'
export const getSystemInfoSync = getSystemInfo
export { addSafeAreaInsets } from './addSafeAreaInsets'
export { getSystemInfo } from './getSystemInfo'
export { getSystemInfoSync } from './getSystemInfoSync'
export { redirectTo } from './redirectTo'
export { previewImage } from './previewImage'
export { navigateTo, initEventChannel, getEventChannel } from './navigateTo'
export * from './types'
import type { EventChannel } from '@dcloudio/uni-shared'
import { MPProtocol } from './types'
const eventChannels: Record<string, EventChannel> = {}
const eventChannelStack: EventChannel[] = []
let id = 0
export function initEventChannel(
events: Record<string, (...args: any[]) => void>,
cache = true
) {
id++
const eventChannel = new __GLOBAL__.EventChannel(id, events)
if (cache) {
eventChannels[id] = eventChannel
eventChannelStack.push(eventChannel)
}
return eventChannel
}
export function getEventChannel(id?: number) {
if (id) {
const eventChannel = eventChannels[id]
delete eventChannels[id]
return eventChannel
}
return eventChannelStack.shift()
}
export const navigateTo: MPProtocol = {
args(fromArgs) {
const id = initEventChannel(fromArgs.events).id
if (fromArgs.url) {
fromArgs.url =
fromArgs.url +
(fromArgs.url.indexOf('?') === -1 ? '?' : '&') +
'__id__=' +
id
}
},
returnValue(fromRes) {
fromRes.eventChannel = getEventChannel()
},
}
import { isArray } from '@vue/shared'
import { MPProtocol } from './types'
export const previewImage: MPProtocol = {
args(
fromArgs: UniApp.PreviewImageOptions,
toArgs: WechatMiniprogram.PreviewImageOption
) {
let currentIndex = parseInt(fromArgs.current as string)
if (isNaN(currentIndex)) {
return
}
const urls = fromArgs.urls
if (!isArray(urls)) {
return
}
const len = urls.length
if (!len) {
return
}
if (currentIndex < 0) {
currentIndex = 0
} else if (currentIndex >= len) {
currentIndex = len - 1
}
if (currentIndex > 0) {
toArgs.current = urls[currentIndex]
toArgs.urls = urls.filter((item, index) =>
index < currentIndex ? item !== urls[currentIndex] : true
)
} else {
toArgs.current = urls[0]
}
return {
indicator: false,
loop: false,
}
},
}
import { isArray } from '@vue/shared'
export type MPProtocolArgsValue = {
name?: string
value: any
......@@ -27,7 +25,7 @@ export type MPProtocolObject = {
returnValue?: MPProtocolReturnValue
}
type MPProtocolFunction = (arg: unknown) => MPProtocolObject
type MPProtocol = MPProtocolObject | MPProtocolFunction
export type MPProtocol = MPProtocolObject | MPProtocolFunction
type MPProtocolsBase = {
[key: string]: MPProtocol
......@@ -41,63 +39,3 @@ type MPProdocolsReturnValue = {
}
export type MPProtocols = MPProtocolsBase | MPProdocolsReturnValue
export const previewImage: MPProtocol = {
args(
fromArgs: UniApp.PreviewImageOptions,
toArgs: WechatMiniprogram.PreviewImageOption
) {
let currentIndex = parseInt(fromArgs.current as string)
if (isNaN(currentIndex)) {
return
}
const urls = fromArgs.urls
if (!isArray(urls)) {
return
}
const len = urls.length
if (!len) {
return
}
if (currentIndex < 0) {
currentIndex = 0
} else if (currentIndex >= len) {
currentIndex = len - 1
}
if (currentIndex > 0) {
toArgs.current = urls[currentIndex]
toArgs.urls = urls.filter((item, index) =>
index < currentIndex ? item !== urls[currentIndex] : true
)
} else {
toArgs.current = urls[0]
}
return {
indicator: false,
loop: false,
}
},
}
export function addSafeAreaInsets(
fromRes: any,
toRes: UniApp.GetSystemInfoResult
) {
if (fromRes.safeArea) {
const safeArea = fromRes.safeArea
toRes.safeAreaInsets = {
top: safeArea.top,
left: safeArea.left,
right: fromRes.windowWidth - safeArea.right,
bottom: fromRes.windowHeight - safeArea.bottom,
}
}
}
export const getSystemInfo = {
returnValue: addSafeAreaInsets,
}
export const getSystemInfoSync = getSystemInfo
export const redirectTo = {}
......@@ -35,6 +35,7 @@ export {
// protocols
export {
redirectTo,
navigateTo,
previewImage,
getSystemInfo,
getSystemInfoSync,
......
import { EventChannel, invokeArrayFns } from '@dcloudio/uni-shared'
import {
capitalize,
hasOwn,
......@@ -8,6 +9,7 @@ import {
} from '@vue/shared'
import { ComponentPublicInstance, ComponentInternalInstance } from 'vue'
import { getEventChannel } from '../api/protocols/navigateTo'
import { MPComponentInstance } from '../index'
function setModel(
......@@ -141,6 +143,20 @@ export function initBaseInstance(
}
}
ctx.getOpenerEventChannel = function () {
// 微信小程序使用自身getOpenerEventChannel
if (__PLATFORM__ === 'mp-weixin') {
return options.mpInstance.getOpenerEventChannel()
}
if (!this.__eventChannel__) {
this.__eventChannel__ = new EventChannel()
}
return this.__eventChannel__
}
ctx.$hasHook = hasHook
ctx.$callHook = callHook
// $emit
instance.emit = createEmitFn(instance.emit, ctx)
}
......@@ -185,3 +201,20 @@ export function initMocks(
}
})
}
function hasHook(this: ComponentPublicInstance, name: string) {
const hooks = (this.$ as any)[name]
if (hooks && hooks.length) {
return true
}
return false
}
function callHook(this: ComponentPublicInstance, name: string, args?: unknown) {
if (name === 'onLoad' && args && (args as any).__id__) {
;(this as any).__eventChannel__ = getEventChannel((args as any).__id__)
delete (args as any).__id__
}
const hooks = (this.$ as any)[name]
return hooks && invokeArrayFns(hooks, args)
}
......@@ -85,7 +85,7 @@ export function findVmByVueId(
instance: ComponentPublicInstance,
vuePid: string
): ComponentPublicInstance | undefined {
// TODO vue3 中 没有 $children
// 标准 vue3 中 没有 $children,定制了内核
const $children = (instance as any).$children
// 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200)
for (let i = $children.length - 1; i >= 0; i--) {
......
import { isArray, hasOwn, isString, isPlainObject, isObject, capitalize, toRawType, makeMap, isPromise, isFunction, extend } from '@vue/shared';
const eventChannels = {};
const eventChannelStack = [];
let id = 0;
function initEventChannel(events, cache = true) {
id++;
const eventChannel = new qq.EventChannel(id, events);
if (cache) {
eventChannels[id] = eventChannel;
eventChannelStack.push(eventChannel);
}
return eventChannel;
}
function getEventChannel(id) {
if (id) {
const eventChannel = eventChannels[id];
delete eventChannels[id];
return eventChannel;
}
return eventChannelStack.shift();
}
const navigateTo = {
args(fromArgs) {
const id = initEventChannel(fromArgs.events).id;
if (fromArgs.url) {
fromArgs.url =
fromArgs.url +
(fromArgs.url.indexOf('?') === -1 ? '?' : '&') +
'__id__=' +
id;
}
},
returnValue(fromRes) {
fromRes.eventChannel = getEventChannel();
},
};
function getBaseSystemInfo() {
return qq.getSystemInfoSync()
}
......@@ -613,6 +649,26 @@ function initGetProvider(providers) {
};
}
function addSafeAreaInsets(fromRes, toRes) {
if (fromRes.safeArea) {
const safeArea = fromRes.safeArea;
toRes.safeAreaInsets = {
top: safeArea.top,
left: safeArea.left,
right: fromRes.windowWidth - safeArea.right,
bottom: fromRes.windowHeight - safeArea.bottom,
};
}
}
const getSystemInfo = {
returnValue: addSafeAreaInsets,
};
const getSystemInfoSync = getSystemInfo;
const redirectTo = {};
const previewImage = {
args(fromArgs, toArgs) {
let currentIndex = parseInt(fromArgs.current);
......@@ -645,23 +701,7 @@ const previewImage = {
loop: false,
};
},
};
function addSafeAreaInsets(fromRes, toRes) {
if (fromRes.safeArea) {
const safeArea = fromRes.safeArea;
toRes.safeAreaInsets = {
top: safeArea.top,
left: safeArea.left,
right: fromRes.windowWidth - safeArea.right,
bottom: fromRes.windowHeight - safeArea.bottom,
};
}
}
const getSystemInfo = {
returnValue: addSafeAreaInsets,
};
const getSystemInfoSync = getSystemInfo;
const redirectTo = {};
};
const getProvider = initGetProvider({
oauth: ['qq'],
......@@ -678,6 +718,7 @@ var shims = /*#__PURE__*/Object.freeze({
var protocols = /*#__PURE__*/Object.freeze({
__proto__: null,
redirectTo: redirectTo,
navigateTo: navigateTo,
previewImage: previewImage,
getSystemInfo: getSystemInfo,
getSystemInfoSync: getSystemInfoSync
......
import { isArray, hasOwn, toNumber, isPlainObject, isObject, isFunction, extend, NOOP, camelize } from '@vue/shared';
import { isPlainObject, isArray, hasOwn, toNumber, isObject, isFunction, extend, NOOP, camelize } from '@vue/shared';
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}` : '';
}
const invokeArrayFns = (fns, arg) => {
let ret;
for (let i = 0; i < fns.length; i++) {
ret = fns[i](arg);
}
return ret;
};
// 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';
const ON_ADD_TO_FAVORITES = 'onAddToFavorites';
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();
}
function setModel(target, key, value, modifiers) {
if (isArray(modifiers)) {
......@@ -82,6 +202,14 @@ function initBaseInstance(instance, options) {
});
}
}
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);
}
......@@ -111,46 +239,22 @@ function initMocks(instance, mpInstance, mocks) {
ctx[mock] = mpInstance[mock];
}
});
}
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}` : '';
}
// 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';
const ON_ADD_TO_FAVORITES = 'onAddToFavorites';
function hasHook(name) {
const hooks = this.$[name];
if (hooks && hooks.length) {
return true;
}
return false;
}
function callHook(name, args) {
if (name === 'onLoad' && args && args.__id__) {
this.__eventChannel__ = getEventChannel(args.__id__);
delete args.__id__;
}
const hooks = this.$[name];
return hooks && invokeArrayFns(hooks, args);
}
const PAGE_HOOKS = [
ON_LOAD,
......@@ -304,7 +408,7 @@ function initRefs(instance, mpInstance) {
});
}
function findVmByVueId(instance, vuePid) {
// TODO vue3 中 没有 $children
// 标准 vue3 中 没有 $children,定制了内核
const $children = instance.$children;
// 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200)
for (let i = $children.length - 1; i >= 0; i--) {
......@@ -916,12 +1020,12 @@ function handleLink(event) {
}
var parseOptions = /*#__PURE__*/Object.freeze({
__proto__: null,
mocks: mocks,
isPage: isPage,
initRelation: initRelation,
handleLink: handleLink,
initLifetimes: initLifetimes
__proto__: null,
mocks: mocks,
isPage: isPage,
initRelation: initRelation,
handleLink: handleLink,
initLifetimes: initLifetimes
});
const createApp = initCreateApp();
......@@ -931,6 +1035,7 @@ wx.createApp = createApp;
wx.createPage = createPage;
wx.createComponent = createComponent;
qq.EventChannel = EventChannel;
qq.createApp = createApp;
qq.createPage = createPage;
qq.createComponent = createComponent;
......
export {
redirectTo,
navigateTo,
previewImage,
getSystemInfo,
getSystemInfoSync,
......
import { EventChannel } from '@dcloudio/uni-shared'
import {
createApp,
createPage,
createComponent,
} from '@dcloudio/uni-mp-weixin/src/runtime'
export * from '@dcloudio/uni-mp-weixin/src/runtime'
;(qq as any).EventChannel = EventChannel
;(qq as any).createApp = createApp
;(qq as any).createPage = createPage
;(qq as any).createComponent = createComponent
import { isArray, hasOwn, isString, isPlainObject, isObject, capitalize, toRawType, makeMap, isPromise, isFunction, extend } from '@vue/shared';
const eventChannels = {};
const eventChannelStack = [];
let id = 0;
function initEventChannel(events, cache = true) {
id++;
const eventChannel = new tt.EventChannel(id, events);
if (cache) {
eventChannels[id] = eventChannel;
eventChannelStack.push(eventChannel);
}
return eventChannel;
}
function getEventChannel(id) {
if (id) {
const eventChannel = eventChannels[id];
delete eventChannels[id];
return eventChannel;
}
return eventChannelStack.shift();
}
const navigateTo = {
args(fromArgs) {
const id = initEventChannel(fromArgs.events).id;
if (fromArgs.url) {
fromArgs.url =
fromArgs.url +
(fromArgs.url.indexOf('?') === -1 ? '?' : '&') +
'__id__=' +
id;
}
},
returnValue(fromRes) {
fromRes.eventChannel = getEventChannel();
},
};
function getBaseSystemInfo() {
return tt.getSystemInfoSync()
}
......@@ -613,6 +649,8 @@ function initGetProvider(providers) {
};
}
const redirectTo = {};
const previewImage = {
args(fromArgs, toArgs) {
let currentIndex = parseInt(fromArgs.current);
......@@ -645,8 +683,7 @@ const previewImage = {
loop: false,
};
},
};
const redirectTo = {};
};
const getProvider = initGetProvider({
oauth: ['toutiao'],
......@@ -748,6 +785,7 @@ var protocols = /*#__PURE__*/Object.freeze({
requestPayment: requestPayment,
getFileInfo: getFileInfo,
redirectTo: redirectTo,
navigateTo: navigateTo,
previewImage: previewImage
});
......
import { isArray, hasOwn, toNumber, isPlainObject, isObject, isFunction, extend, NOOP, camelize } from '@vue/shared';
import { isPlainObject, isArray, hasOwn, toNumber, isObject, isFunction, extend, NOOP, camelize } from '@vue/shared';
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}` : '';
}
const invokeArrayFns = (fns, arg) => {
let ret;
for (let i = 0; i < fns.length; i++) {
ret = fns[i](arg);
}
return ret;
};
// 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';
const ON_ADD_TO_FAVORITES = 'onAddToFavorites';
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();
}
function setModel(target, key, value, modifiers) {
if (isArray(modifiers)) {
......@@ -82,6 +202,14 @@ function initBaseInstance(instance, options) {
});
}
}
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);
}
......@@ -111,46 +239,22 @@ function initMocks(instance, mpInstance, mocks) {
ctx[mock] = mpInstance[mock];
}
});
}
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}` : '';
}
// 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';
const ON_ADD_TO_FAVORITES = 'onAddToFavorites';
function hasHook(name) {
const hooks = this.$[name];
if (hooks && hooks.length) {
return true;
}
return false;
}
function callHook(name, args) {
if (name === 'onLoad' && args && args.__id__) {
this.__eventChannel__ = getEventChannel(args.__id__);
delete args.__id__;
}
const hooks = this.$[name];
return hooks && invokeArrayFns(hooks, args);
}
const PAGE_HOOKS = [
ON_LOAD,
......@@ -307,7 +411,7 @@ function initRefs(instance, mpInstance) {
});
}
function findVmByVueId(instance, vuePid) {
// TODO vue3 中 没有 $children
// 标准 vue3 中 没有 $children,定制了内核
const $children = instance.$children;
// 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200)
for (let i = $children.length - 1; i >= 0; i--) {
......@@ -1037,14 +1141,14 @@ function parse(componentOptions, { handleLink }) {
}
var parseComponentOptions = /*#__PURE__*/Object.freeze({
__proto__: null,
mocks: mocks,
isPage: isPage,
instances: instances,
initRelation: initRelation,
handleLink: handleLink,
parse: parse,
initLifetimes: initLifetimes$1
__proto__: null,
mocks: mocks,
isPage: isPage,
instances: instances,
initRelation: initRelation,
handleLink: handleLink,
parse: parse,
initLifetimes: initLifetimes$1
});
function initLifetimes(lifetimesOptions) {
......@@ -1074,18 +1178,19 @@ function initLifetimes(lifetimesOptions) {
}
var parsePageOptions = /*#__PURE__*/Object.freeze({
__proto__: null,
mocks: mocks,
isPage: isPage,
initRelation: initRelation,
handleLink: handleLink,
parse: parse,
initLifetimes: initLifetimes
__proto__: null,
mocks: mocks,
isPage: isPage,
initRelation: initRelation,
handleLink: handleLink,
parse: parse,
initLifetimes: initLifetimes
});
const createApp = initCreateApp();
const createPage = initCreatePage(parsePageOptions);
const createComponent = initCreateComponent(parseComponentOptions);
tt.EventChannel = EventChannel;
tt.createApp = createApp;
tt.createPage = createPage;
tt.createComponent = createComponent;
......
export { redirectTo, previewImage } from '@dcloudio/uni-mp-core'
export { redirectTo, navigateTo, previewImage } from '@dcloudio/uni-mp-core'
export const chooseImage = {
args: {
sizeType: false,
......
import { EventChannel } from '@dcloudio/uni-shared'
import {
initCreateApp,
initCreatePage,
......@@ -12,6 +13,7 @@ import * as parseComponentOptions from './parseComponentOptions'
export const createApp = initCreateApp()
export const createPage = initCreatePage(parsePageOptions)
export const createComponent = initCreateComponent(parseComponentOptions)
;(tt as any).EventChannel = EventChannel
;(tt as any).createApp = createApp
;(tt as any).createPage = createPage
;(tt as any).createComponent = createComponent
......@@ -613,6 +613,26 @@ function initGetProvider(providers) {
};
}
function addSafeAreaInsets(fromRes, toRes) {
if (fromRes.safeArea) {
const safeArea = fromRes.safeArea;
toRes.safeAreaInsets = {
top: safeArea.top,
left: safeArea.left,
right: fromRes.windowWidth - safeArea.right,
bottom: fromRes.windowHeight - safeArea.bottom,
};
}
}
const getSystemInfo = {
returnValue: addSafeAreaInsets,
};
const getSystemInfoSync = getSystemInfo;
const redirectTo = {};
const previewImage = {
args(fromArgs, toArgs) {
let currentIndex = parseInt(fromArgs.current);
......@@ -645,23 +665,7 @@ const previewImage = {
loop: false,
};
},
};
function addSafeAreaInsets(fromRes, toRes) {
if (fromRes.safeArea) {
const safeArea = fromRes.safeArea;
toRes.safeAreaInsets = {
top: safeArea.top,
left: safeArea.left,
right: fromRes.windowWidth - safeArea.right,
bottom: fromRes.windowHeight - safeArea.bottom,
};
}
}
const getSystemInfo = {
returnValue: addSafeAreaInsets,
};
const getSystemInfoSync = getSystemInfo;
const redirectTo = {};
};
const getProvider = initGetProvider({
oauth: ['weixin'],
......
import { isArray, hasOwn, toNumber, isPlainObject, isObject, isFunction, extend, NOOP, camelize } from '@vue/shared';
import { isPlainObject, isArray, hasOwn, toNumber, isObject, isFunction, extend, NOOP, camelize } from '@vue/shared';
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}` : '';
}
const invokeArrayFns = (fns, arg) => {
let ret;
for (let i = 0; i < fns.length; i++) {
ret = fns[i](arg);
}
return ret;
};
// 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';
const ON_ADD_TO_FAVORITES = 'onAddToFavorites';
const eventChannels = {};
const eventChannelStack = [];
function getEventChannel(id) {
if (id) {
const eventChannel = eventChannels[id];
delete eventChannels[id];
return eventChannel;
}
return eventChannelStack.shift();
}
function setModel(target, key, value, modifiers) {
if (isArray(modifiers)) {
......@@ -82,6 +139,14 @@ function initBaseInstance(instance, options) {
});
}
}
ctx.getOpenerEventChannel = function () {
// 微信小程序使用自身getOpenerEventChannel
{
return options.mpInstance.getOpenerEventChannel();
}
};
ctx.$hasHook = hasHook;
ctx.$callHook = callHook;
// $emit
instance.emit = createEmitFn(instance.emit, ctx);
}
......@@ -111,46 +176,22 @@ function initMocks(instance, mpInstance, mocks) {
ctx[mock] = mpInstance[mock];
}
});
}
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}` : '';
}
// 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';
const ON_ADD_TO_FAVORITES = 'onAddToFavorites';
function hasHook(name) {
const hooks = this.$[name];
if (hooks && hooks.length) {
return true;
}
return false;
}
function callHook(name, args) {
if (name === 'onLoad' && args && args.__id__) {
this.__eventChannel__ = getEventChannel(args.__id__);
delete args.__id__;
}
const hooks = this.$[name];
return hooks && invokeArrayFns(hooks, args);
}
const PAGE_HOOKS = [
ON_LOAD,
......@@ -304,7 +345,7 @@ function initRefs(instance, mpInstance) {
});
}
function findVmByVueId(instance, vuePid) {
// TODO vue3 中 没有 $children
// 标准 vue3 中 没有 $children,定制了内核
const $children = instance.$children;
// 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200)
for (let i = $children.length - 1; i >= 0; i--) {
......@@ -916,12 +957,12 @@ function handleLink(event) {
}
var parseOptions = /*#__PURE__*/Object.freeze({
__proto__: null,
mocks: mocks,
isPage: isPage,
initRelation: initRelation,
handleLink: handleLink,
initLifetimes: initLifetimes
__proto__: null,
mocks: mocks,
isPage: isPage,
initRelation: initRelation,
handleLink: handleLink,
initLifetimes: initLifetimes
});
const createApp = initCreateApp();
......
import { isArray, hasOwn, isString, isPlainObject, isObject, capitalize, toRawType, makeMap, isPromise, isFunction, extend } from '@vue/shared';
const eventChannels = {};
const eventChannelStack = [];
let id = 0;
function initEventChannel(events, cache = true) {
id++;
const eventChannel = new qa.EventChannel(id, events);
if (cache) {
eventChannels[id] = eventChannel;
eventChannelStack.push(eventChannel);
}
return eventChannel;
}
function getEventChannel(id) {
if (id) {
const eventChannel = eventChannels[id];
delete eventChannels[id];
return eventChannel;
}
return eventChannelStack.shift();
}
const navigateTo = {
args(fromArgs) {
const id = initEventChannel(fromArgs.events).id;
if (fromArgs.url) {
fromArgs.url =
fromArgs.url +
(fromArgs.url.indexOf('?') === -1 ? '?' : '&') +
'__id__=' +
id;
}
},
returnValue(fromRes) {
fromRes.eventChannel = getEventChannel();
},
};
function getBaseSystemInfo() {
return qa.getSystemInfoSync()
}
......@@ -613,6 +649,26 @@ function initGetProvider(providers) {
};
}
function addSafeAreaInsets(fromRes, toRes) {
if (fromRes.safeArea) {
const safeArea = fromRes.safeArea;
toRes.safeAreaInsets = {
top: safeArea.top,
left: safeArea.left,
right: fromRes.windowWidth - safeArea.right,
bottom: fromRes.windowHeight - safeArea.bottom,
};
}
}
const getSystemInfo = {
returnValue: addSafeAreaInsets,
};
const getSystemInfoSync = getSystemInfo;
const redirectTo = {};
const previewImage = {
args(fromArgs, toArgs) {
let currentIndex = parseInt(fromArgs.current);
......@@ -645,23 +701,7 @@ const previewImage = {
loop: false,
};
},
};
function addSafeAreaInsets(fromRes, toRes) {
if (fromRes.safeArea) {
const safeArea = fromRes.safeArea;
toRes.safeAreaInsets = {
top: safeArea.top,
left: safeArea.left,
right: fromRes.windowWidth - safeArea.right,
bottom: fromRes.windowHeight - safeArea.bottom,
};
}
}
const getSystemInfo = {
returnValue: addSafeAreaInsets,
};
const getSystemInfoSync = getSystemInfo;
const redirectTo = {};
};
const providers = {
oauth: [],
......@@ -685,6 +725,7 @@ var shims = /*#__PURE__*/Object.freeze({
var protocols = /*#__PURE__*/Object.freeze({
__proto__: null,
redirectTo: redirectTo,
navigateTo: navigateTo,
previewImage: previewImage,
getSystemInfo: getSystemInfo,
getSystemInfoSync: getSystemInfoSync
......
import { isArray, hasOwn, toNumber, isPlainObject, isObject, isFunction, extend, NOOP, camelize } from '@vue/shared';
import { isPlainObject, isArray, hasOwn, toNumber, isObject, isFunction, extend, NOOP, camelize } from '@vue/shared';
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}` : '';
}
const invokeArrayFns = (fns, arg) => {
let ret;
for (let i = 0; i < fns.length; i++) {
ret = fns[i](arg);
}
return ret;
};
// 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';
const ON_ADD_TO_FAVORITES = 'onAddToFavorites';
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();
}
function setModel(target, key, value, modifiers) {
if (isArray(modifiers)) {
......@@ -82,6 +202,14 @@ function initBaseInstance(instance, options) {
});
}
}
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);
}
......@@ -111,46 +239,22 @@ function initMocks(instance, mpInstance, mocks) {
ctx[mock] = mpInstance[mock];
}
});
}
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}` : '';
}
// 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';
const ON_ADD_TO_FAVORITES = 'onAddToFavorites';
function hasHook(name) {
const hooks = this.$[name];
if (hooks && hooks.length) {
return true;
}
return false;
}
function callHook(name, args) {
if (name === 'onLoad' && args && args.__id__) {
this.__eventChannel__ = getEventChannel(args.__id__);
delete args.__id__;
}
const hooks = this.$[name];
return hooks && invokeArrayFns(hooks, args);
}
const PAGE_HOOKS = [
ON_LOAD,
......@@ -1050,28 +1154,29 @@ function handleLink({ detail: { nodeId, webviewId }, }) {
}
var parseComponentOptions = /*#__PURE__*/Object.freeze({
__proto__: null,
initRelation: initRelation,
handleLink: handleLink,
mocks: mocks,
isPage: isPage,
parse: parse,
initLifetimes: initLifetimes$1
__proto__: null,
initRelation: initRelation,
handleLink: handleLink,
mocks: mocks,
isPage: isPage,
parse: parse,
initLifetimes: initLifetimes$1
});
var parsePageOptions = /*#__PURE__*/Object.freeze({
__proto__: null,
mocks: mocks,
isPage: isPage,
initRelation: initRelation,
handleLink: handleLink,
parse: parse,
initLifetimes: initLifetimes
__proto__: null,
mocks: mocks,
isPage: isPage,
initRelation: initRelation,
handleLink: handleLink,
parse: parse,
initLifetimes: initLifetimes
});
const createApp = initCreateApp();
const createPage = initCreatePage(parsePageOptions);
const createComponent = initCreateComponent(parseComponentOptions);
qa.EventChannel = EventChannel;
qa.createApp = createApp;
qa.createPage = createPage;
qa.createComponent = createComponent;
......
export {
redirectTo,
navigateTo,
previewImage,
getSystemInfo,
getSystemInfoSync,
......
import { EventChannel } from '@dcloudio/uni-shared'
import {
initCreateApp,
initCreatePage,
......@@ -12,6 +13,7 @@ import * as parseComponentOptions from './parseComponentOptions'
export const createApp = initCreateApp()
export const createPage = initCreatePage(parsePageOptions)
export const createComponent = initCreateComponent(parseComponentOptions)
;(qa as any).EventChannel = EventChannel
;(qa as any).createApp = createApp
;(qa as any).createPage = createPage
;(qa as any).createComponent = createComponent
......@@ -6,10 +6,10 @@ interface EventChannelListener {
}
export class EventChannel {
id: number
id?: number
private listener: Record<string, EventChannelListener[]>
private emitCache: Record<string, any[][]>
constructor(id: number, events?: NavigateToOptionEvents) {
constructor(id?: number, events?: NavigateToOptionEvents) {
this.id = id
this.listener = {}
this.emitCache = {}
......
import { ComponentPublicInstance } from 'vue'
import { invokeArrayFns } from '@dcloudio/uni-shared'
export function set(target: any, key: string | number, val: unknown) {
return (target[key] = val)
}
export function hasHook(this: ComponentPublicInstance, name: string) {
const hooks = (this.$ as any)[name]
if (hooks && hooks.length) {
return true
}
return false
}
export function callHook(
this: ComponentPublicInstance,
name: string,
args?: unknown
) {
const hooks = (this.$ as any)[name]
return hooks && invokeArrayFns(hooks, args)
}
......@@ -3,7 +3,7 @@ import { App } from 'vue'
import { isFunction } from '@vue/shared'
import { applyOptions } from './componentOptions'
import { set, hasHook, callHook } from './componentInstance'
import { set } from './componentInstance'
import { errorHandler } from './appConfig'
import { uniIdMixin } from './uni-id-mixin'
......@@ -14,11 +14,6 @@ export function initApp(app: App) {
}
const globalProperties = appConfig.globalProperties
uniIdMixin(globalProperties)
if (__PLATFORM__ !== 'h5' && __PLATFORM__ !== 'app') {
// 小程序,待重构,不再挂靠全局
globalProperties.$hasHook = hasHook
globalProperties.$callHook = callHook
}
if (__VUE_OPTIONS_API__) {
globalProperties.$set = set
globalProperties.$applyOptions = applyOptions
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册