diff --git a/packages/uni-mp-alipay/dist/uni.api.esm.js b/packages/uni-mp-alipay/dist/uni.api.esm.js index 53d09d0492c48ae3443d4c35fdebac96a6b00277..70ac01eb5b6a2fc3756884de936444a51d11d4ad 100644 --- a/packages/uni-mp-alipay/dist/uni.api.esm.js +++ b/packages/uni-mp-alipay/dist/uni.api.esm.js @@ -462,6 +462,114 @@ const removeInterceptor = defineSyncApi(API_REMOVE_INTERCEPTOR, (method, interce } }, RemoveInterceptorProtocol); +const API_ON = '$on'; +const OnProtocol = [ + { + name: 'event', + type: String, + required: true, + }, + { + name: 'callback', + type: Function, + required: true, + }, +]; +const API_ONCE = '$once'; +const OnceProtocol = OnProtocol; +const API_OFF = '$off'; +const OffProtocol = [ + { + name: 'event', + type: [String, Array], + }, + { + name: 'callback', + type: Function, + }, +]; +const API_EMIT = '$emit'; +const EmitProtocol = [ + { + name: 'event', + type: String, + required: true, + }, +]; + +const E = function () { + // Keep this empty so it's easier to inherit from + // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3) +}; +E.prototype = { + on: function (name, callback, ctx) { + var e = this.e || (this.e = {}); + (e[name] || (e[name] = [])).push({ + fn: callback, + ctx: ctx, + }); + return this; + }, + once: function (name, callback, ctx) { + var self = this; + function listener() { + self.off(name, listener); + callback.apply(ctx, arguments); + } + listener._ = callback; + return this.on(name, listener, ctx); + }, + emit: function (name) { + var data = [].slice.call(arguments, 1); + var evtArr = ((this.e || (this.e = {}))[name] || []).slice(); + var i = 0; + var len = evtArr.length; + for (i; i < len; i++) { + evtArr[i].fn.apply(evtArr[i].ctx, data); + } + return this; + }, + off: function (name, callback) { + var e = this.e || (this.e = {}); + var evts = e[name]; + var liveEvents = []; + if (evts && callback) { + for (var i = 0, len = evts.length; i < len; i++) { + if (evts[i].fn !== callback && evts[i].fn._ !== callback) + liveEvents.push(evts[i]); + } + } + // Remove event from queue to prevent memory leak + // Suggested by https://github.com/lazd + // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910 + liveEvents.length ? (e[name] = liveEvents) : delete e[name]; + return this; + }, +}; +var Emitter = E; + +const emitter = new Emitter(); +const $on = defineSyncApi(API_ON, (name, callback) => { + emitter.on(name, callback); + return () => emitter.off(name, callback); +}, OnProtocol); +const $once = defineSyncApi(API_ONCE, (name, callback) => { + emitter.once(name, callback); + return () => emitter.off(name, callback); +}, OnceProtocol); +const $off = defineSyncApi(API_OFF, (name, callback) => { + if (!name) { + emitter.e = {}; + return; + } + if (!Array.isArray(name)) + name = [name]; + name.forEach((n) => emitter.off(n, callback)); +}, OffProtocol); +const $emit = defineSyncApi(API_EMIT, (name, ...args) => { + emitter.emit(name, ...args); +}, EmitProtocol); + const SYNC_API_RE = /^\$|sendNativeEvent|restoreGlobal|getCurrentSubNVue|getMenuButtonBoundingClientRect|^report|interceptors|Interceptor$|getSubNVueById|requireNativePlugin|upx2px|hideKeyboard|canIUse|^create|Sync$|Manager$|base64ToArrayBuffer|arrayBufferToBase64/; const CONTEXT_API_RE = /^create|Manager$/; // Context例外情况 @@ -606,7 +714,15 @@ function initWrapper(protocols) { }; } -const baseApis = { upx2px, addInterceptor, removeInterceptor }; +const baseApis = { + $on, + $off, + $once, + $emit, + upx2px, + addInterceptor, + removeInterceptor, +}; function initUni(api, protocols) { const wrapper = initWrapper(protocols); const UniProxyHandlers = { diff --git a/packages/uni-mp-alipay/dist/uni.mp.esm.js b/packages/uni-mp-alipay/dist/uni.mp.esm.js index 4b2de683d6031b0c5ae46f3bea4aabc8ef7c6798..29e6a327c0f65410cf870a64b7d6efc77ce6fbe9 100644 --- a/packages/uni-mp-alipay/dist/uni.mp.esm.js +++ b/packages/uni-mp-alipay/dist/uni.mp.esm.js @@ -1,4 +1,4 @@ -import { isPlainObject, hasOwn, isArray, toNumber, isObject, capitalize, isFunction, extend, NOOP, EMPTY_OBJ, camelize } from '@vue/shared'; +import { isPlainObject, isArray, extend, hyphenate, isObject, hasOwn, toNumber, capitalize, isFunction, NOOP, EMPTY_OBJ, camelize } from '@vue/shared'; const encode = encodeURIComponent; function stringifyQuery(obj, encodeStr = encode) { @@ -19,6 +19,14 @@ function stringifyQuery(obj, encodeStr = encode) { : null; return res ? `?${res}` : ''; } + +function cache(fn) { + const cache = Object.create(null); + return (str) => { + const hit = cache[str]; + return hit || (cache[str] = fn(str)); + }; +} const invokeArrayFns = (fns, arg) => { let ret; for (let i = 0; i < fns.length; i++) { @@ -121,6 +129,167 @@ function getEventChannel(id) { return eventChannelStack.shift(); } +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]; + } +} +function initWxsCallMethods(methods, wxsCallMethods) { + if (!isArray(wxsCallMethods)) { + return; + } + wxsCallMethods.forEach((callMethod) => { + methods[callMethod] = function (args) { + return this.$vm[callMethod](args); + }; + }); +} +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; + } + } +} +function getTarget(obj, path) { + const parts = path.split('.'); + let key = parts[0]; + if (key.indexOf('__$n') === 0) { + //number index + key = parseInt(key.replace('__$n', '')); + } + if (!obj) { + obj = {}; + } + if (parts.length === 1) { + return obj[key]; + } + return getTarget(obj[key], parts.slice(1).join('.')); +} + +function getValue(dataPath, target) { + return getTarget(target || this, dataPath); +} +function getClass(dynamicClass, staticClass) { + return renderClass(staticClass, dynamicClass); +} +function getStyle(dynamicStyle, staticStyle) { + if (!dynamicStyle && !staticStyle) { + return ''; + } + var dynamicStyleObj = normalizeStyleBinding(dynamicStyle); + var styleObj = staticStyle + ? extend(staticStyle, dynamicStyleObj) + : dynamicStyleObj; + return Object.keys(styleObj) + .map(function (name) { + return hyphenate(name) + ':' + styleObj[name]; + }) + .join(';'); +} +function toObject(arr) { + var res = {}; + for (var i = 0; i < arr.length; i++) { + if (arr[i]) { + extend(res, arr[i]); + } + } + return res; +} +function normalizeStyleBinding(bindingStyle) { + if (Array.isArray(bindingStyle)) { + return toObject(bindingStyle); + } + if (typeof bindingStyle === 'string') { + return parseStyleText(bindingStyle); + } + return bindingStyle; +} +var parseStyleText = cache(function parseStyleText(cssText) { + var res = {}; + var listDelimiter = /;(?![^(]*\))/g; + var propertyDelimiter = /:(.+)/; + cssText.split(listDelimiter).forEach(function (item) { + if (item) { + var tmp = item.split(propertyDelimiter); + tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim()); + } + }); + return res; +}); +function isDef(v) { + return v !== undefined && v !== null; +} +function renderClass(staticClass, dynamicClass) { + if (isDef(staticClass) || isDef(dynamicClass)) { + return concat(staticClass, stringifyClass(dynamicClass)); + } + /* istanbul ignore next */ + return ''; +} +function concat(a, b) { + return a ? (b ? a + ' ' + b : a) : b || ''; +} +function stringifyClass(value) { + if (Array.isArray(value)) { + return stringifyArray(value); + } + if (isObject(value)) { + return stringifyObject(value); + } + if (typeof value === 'string') { + return value; + } + /* istanbul ignore next */ + return ''; +} +function stringifyArray(value) { + var res = ''; + var stringified; + for (var i = 0, l = value.length; i < l; i++) { + if (isDef((stringified = stringifyClass(value[i]))) && stringified !== '') { + if (res) { + res += ' '; + } + res += stringified; + } + } + return res; +} +function stringifyObject(value) { + var res = ''; + for (var key in value) { + if (value[key]) { + if (res) { + res += ' '; + } + res += key; + } + } + return res; +} + function setModel(target, key, value, modifiers) { if (isArray(modifiers)) { if (modifiers.indexOf('trim') !== -1) { @@ -239,7 +408,9 @@ function initComponentInstance(instance, options) { ctx.__set_sync = setSync; ctx.__get_orig = getOrig; // TODO - // ctx.__get_style = getStyle + ctx.__get_value = getValue; + ctx.__get_class = getClass; + ctx.__get_style = getStyle; ctx.__map = map; } function initMocks(instance, mpInstance, mocks) { @@ -366,50 +537,6 @@ function initCreateApp(parseAppOptions) { }; } -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]; - } -} -function initWxsCallMethods(methods, wxsCallMethods) { - if (!isArray(wxsCallMethods)) { - return; - } - wxsCallMethods.forEach((callMethod) => { - methods[callMethod] = function (args) { - return this.$vm[callMethod](args); - }; - }); -} -function findVmByVueId(instance, vuePid) { - // 标准 vue3 中 没有 $children,定制了内核 - const $children = instance.$children; - // 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200) - for (let i = $children.length - 1; i >= 0; i--) { - const childVm = $children[i]; - if (childVm.$scope._$vueId === vuePid) { - return childVm; - } - } - // 反向递归查找 - let parentVm; - for (let i = $children.length - 1; i >= 0; i--) { - parentVm = findVmByVueId($children[i], vuePid); - if (parentVm) { - return parentVm; - } - } -} - const PROP_TYPES = [String, Number, Boolean, Object, Array, null]; function parsePropType(key, type, defaultValue) { // [String]=>String @@ -556,18 +683,6 @@ function initBehaviors(vueOptions, initBehavior) { return behaviors; } -function getValue(obj, path) { - const parts = path.split('.'); - let key = parts[0]; - if (key.indexOf('__$n') === 0) { - //number index - key = parseInt(key.replace('__$n', '')); - } - if (parts.length === 1) { - return obj[key]; - } - return getValue(obj[key], parts.slice(1).join('.')); -} function getExtraValue(instance, dataPathsArray) { let context = instance; dataPathsArray.forEach((dataPathArray) => { @@ -589,7 +704,7 @@ function getExtraValue(instance, dataPathsArray) { vFor = dataPath.substr(3); } else { - vFor = getValue(context, dataPath); + vFor = getTarget(context, dataPath); } } if (Number.isInteger(vFor)) { @@ -601,12 +716,12 @@ function getExtraValue(instance, dataPathsArray) { else { if (isArray(vFor)) { context = vFor.find((vForItem) => { - return getValue(vForItem, propPath) === value; + return getTarget(vForItem, propPath) === value; }); } else if (isPlainObject(vFor)) { context = Object.keys(vFor).find((vForKey) => { - return getValue(vFor[vForKey], propPath) === value; + return getTarget(vFor[vForKey], propPath) === value; }); } else { @@ -614,7 +729,7 @@ function getExtraValue(instance, dataPathsArray) { } } if (valuePath) { - context = getValue(context, valuePath); + context = getTarget(context, valuePath); } } }); @@ -655,10 +770,10 @@ function processEventExtra(instance, extra, event) { } else if (dataPath.indexOf('$event.') === 0) { // $event.target.value - extraObj['$' + index] = getValue(event, dataPath.replace('$event.', '')); + extraObj['$' + index] = getTarget(event, dataPath.replace('$event.', '')); } else { - extraObj['$' + index] = getValue(instance, dataPath); + extraObj['$' + index] = getTarget(instance, dataPath); } } } @@ -795,7 +910,14 @@ function handleEvent(event) { } handler.once = true; } - ret.push(handler.apply(handlerCtx, processEventArgs(this.$vm, event, eventArray[1], eventArray[2], isCustom, methodName))); + let params = processEventArgs(this.$vm, event, eventArray[1], eventArray[2], isCustom, methodName); + params = Array.isArray(params) ? params : []; + // 参数尾部增加原始事件对象用于复杂表达式内获取额外数据 + if (/=\s*\S+\.eventParams\s*\|\|\s*\S+\[['"]event-params['"]\]/.test(handler.toString())) { + // eslint-disable-next-line no-sparse-arrays + params = params.concat([, , , , , , , , , , event]); + } + ret.push(handler.apply(handlerCtx, params)); } }); } diff --git a/packages/uni-mp-baidu/dist/uni.api.esm.js b/packages/uni-mp-baidu/dist/uni.api.esm.js index 28f70583f2cd0fd55f206351b83a9ec5ffba6088..eb8b2d96185c84f1804493d29d62fe5061b428c0 100644 --- a/packages/uni-mp-baidu/dist/uni.api.esm.js +++ b/packages/uni-mp-baidu/dist/uni.api.esm.js @@ -462,6 +462,114 @@ const removeInterceptor = defineSyncApi(API_REMOVE_INTERCEPTOR, (method, interce } }, RemoveInterceptorProtocol); +const API_ON = '$on'; +const OnProtocol = [ + { + name: 'event', + type: String, + required: true, + }, + { + name: 'callback', + type: Function, + required: true, + }, +]; +const API_ONCE = '$once'; +const OnceProtocol = OnProtocol; +const API_OFF = '$off'; +const OffProtocol = [ + { + name: 'event', + type: [String, Array], + }, + { + name: 'callback', + type: Function, + }, +]; +const API_EMIT = '$emit'; +const EmitProtocol = [ + { + name: 'event', + type: String, + required: true, + }, +]; + +const E = function () { + // Keep this empty so it's easier to inherit from + // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3) +}; +E.prototype = { + on: function (name, callback, ctx) { + var e = this.e || (this.e = {}); + (e[name] || (e[name] = [])).push({ + fn: callback, + ctx: ctx, + }); + return this; + }, + once: function (name, callback, ctx) { + var self = this; + function listener() { + self.off(name, listener); + callback.apply(ctx, arguments); + } + listener._ = callback; + return this.on(name, listener, ctx); + }, + emit: function (name) { + var data = [].slice.call(arguments, 1); + var evtArr = ((this.e || (this.e = {}))[name] || []).slice(); + var i = 0; + var len = evtArr.length; + for (i; i < len; i++) { + evtArr[i].fn.apply(evtArr[i].ctx, data); + } + return this; + }, + off: function (name, callback) { + var e = this.e || (this.e = {}); + var evts = e[name]; + var liveEvents = []; + if (evts && callback) { + for (var i = 0, len = evts.length; i < len; i++) { + if (evts[i].fn !== callback && evts[i].fn._ !== callback) + liveEvents.push(evts[i]); + } + } + // Remove event from queue to prevent memory leak + // Suggested by https://github.com/lazd + // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910 + liveEvents.length ? (e[name] = liveEvents) : delete e[name]; + return this; + }, +}; +var Emitter = E; + +const emitter = new Emitter(); +const $on = defineSyncApi(API_ON, (name, callback) => { + emitter.on(name, callback); + return () => emitter.off(name, callback); +}, OnProtocol); +const $once = defineSyncApi(API_ONCE, (name, callback) => { + emitter.once(name, callback); + return () => emitter.off(name, callback); +}, OnceProtocol); +const $off = defineSyncApi(API_OFF, (name, callback) => { + if (!name) { + emitter.e = {}; + return; + } + if (!Array.isArray(name)) + name = [name]; + name.forEach((n) => emitter.off(n, callback)); +}, OffProtocol); +const $emit = defineSyncApi(API_EMIT, (name, ...args) => { + emitter.emit(name, ...args); +}, EmitProtocol); + const SYNC_API_RE = /^\$|sendNativeEvent|restoreGlobal|getCurrentSubNVue|getMenuButtonBoundingClientRect|^report|interceptors|Interceptor$|getSubNVueById|requireNativePlugin|upx2px|hideKeyboard|canIUse|^create|Sync$|Manager$|base64ToArrayBuffer|arrayBufferToBase64/; const CONTEXT_API_RE = /^create|Manager$/; // Context例外情况 @@ -606,7 +714,15 @@ function initWrapper(protocols) { }; } -const baseApis = { upx2px, addInterceptor, removeInterceptor }; +const baseApis = { + $on, + $off, + $once, + $emit, + upx2px, + addInterceptor, + removeInterceptor, +}; function initUni(api, protocols) { const wrapper = initWrapper(protocols); const UniProxyHandlers = { diff --git a/packages/uni-mp-baidu/dist/uni.mp.esm.js b/packages/uni-mp-baidu/dist/uni.mp.esm.js index 9e549b0e9764ce40d03e21500a8a4e3791430d57..28c53ea2ebbe50e0fa76a182406df0fa6ae1e279 100644 --- a/packages/uni-mp-baidu/dist/uni.mp.esm.js +++ b/packages/uni-mp-baidu/dist/uni.mp.esm.js @@ -1,4 +1,4 @@ -import { isPlainObject, isArray, hasOwn, toNumber, isObject, isFunction, extend, NOOP, camelize } from '@vue/shared'; +import { isPlainObject, hasOwn, isArray, extend, hyphenate, isObject, toNumber, isFunction, NOOP, camelize } from '@vue/shared'; const encode = encodeURIComponent; function stringifyQuery(obj, encodeStr = encode) { @@ -19,6 +19,14 @@ function stringifyQuery(obj, encodeStr = encode) { : null; return res ? `?${res}` : ''; } + +function cache(fn) { + const cache = Object.create(null); + return (str) => { + const hit = cache[str]; + return hit || (cache[str] = fn(str)); + }; +} const invokeArrayFns = (fns, arg) => { let ret; for (let i = 0; i < fns.length; i++) { @@ -120,6 +128,202 @@ function getEventChannel(id) { return eventChannelStack.shift(); } +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) => { + const ref = component.dataset.ref; + $refs[ref] = component.$vm || component; + }); +} +function initRefs(instance, mpInstance) { + Object.defineProperty(instance, 'refs', { + get() { + const $refs = {}; + selectAllComponents(mpInstance, '.vue-ref', $refs); + const forComponents = mpInstance.selectAllComponents('.vue-ref-in-for'); + forComponents.forEach((component) => { + const ref = component.dataset.ref; + 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; + } + } +} +function getTarget(obj, path) { + const parts = path.split('.'); + let key = parts[0]; + if (key.indexOf('__$n') === 0) { + //number index + key = parseInt(key.replace('__$n', '')); + } + if (!obj) { + obj = {}; + } + if (parts.length === 1) { + return obj[key]; + } + return getTarget(obj[key], parts.slice(1).join('.')); +} + +function getValue(dataPath, target) { + return getTarget(target || this, dataPath); +} +function getClass(dynamicClass, staticClass) { + return renderClass(staticClass, dynamicClass); +} +function getStyle(dynamicStyle, staticStyle) { + if (!dynamicStyle && !staticStyle) { + return ''; + } + var dynamicStyleObj = normalizeStyleBinding(dynamicStyle); + var styleObj = staticStyle + ? extend(staticStyle, dynamicStyleObj) + : dynamicStyleObj; + return Object.keys(styleObj) + .map(function (name) { + return hyphenate(name) + ':' + styleObj[name]; + }) + .join(';'); +} +function toObject(arr) { + var res = {}; + for (var i = 0; i < arr.length; i++) { + if (arr[i]) { + extend(res, arr[i]); + } + } + return res; +} +function normalizeStyleBinding(bindingStyle) { + if (Array.isArray(bindingStyle)) { + return toObject(bindingStyle); + } + if (typeof bindingStyle === 'string') { + return parseStyleText(bindingStyle); + } + return bindingStyle; +} +var parseStyleText = cache(function parseStyleText(cssText) { + var res = {}; + var listDelimiter = /;(?![^(]*\))/g; + var propertyDelimiter = /:(.+)/; + cssText.split(listDelimiter).forEach(function (item) { + if (item) { + var tmp = item.split(propertyDelimiter); + tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim()); + } + }); + return res; +}); +function isDef(v) { + return v !== undefined && v !== null; +} +function renderClass(staticClass, dynamicClass) { + if (isDef(staticClass) || isDef(dynamicClass)) { + return concat(staticClass, stringifyClass(dynamicClass)); + } + /* istanbul ignore next */ + return ''; +} +function concat(a, b) { + return a ? (b ? a + ' ' + b : a) : b || ''; +} +function stringifyClass(value) { + if (Array.isArray(value)) { + return stringifyArray(value); + } + if (isObject(value)) { + return stringifyObject(value); + } + if (typeof value === 'string') { + return value; + } + /* istanbul ignore next */ + return ''; +} +function stringifyArray(value) { + var res = ''; + var stringified; + for (var i = 0, l = value.length; i < l; i++) { + if (isDef((stringified = stringifyClass(value[i]))) && stringified !== '') { + if (res) { + res += ' '; + } + res += stringified; + } + } + return res; +} +function stringifyObject(value) { + var res = ''; + for (var key in value) { + if (value[key]) { + if (res) { + res += ' '; + } + res += key; + } + } + return res; +} + function setModel(target, key, value, modifiers) { if (isArray(modifiers)) { if (modifiers.indexOf('trim') !== -1) { @@ -229,7 +433,9 @@ function initComponentInstance(instance, options) { ctx.__set_sync = setSync; ctx.__get_orig = getOrig; // TODO - // ctx.__get_style = getStyle + ctx.__get_value = getValue; + ctx.__get_class = getClass; + ctx.__get_style = getStyle; ctx.__map = map; } function initMocks(instance, mpInstance, mocks) { @@ -356,85 +562,6 @@ function initCreateApp(parseAppOptions) { }; } -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) => { - const ref = component.dataset.ref; - $refs[ref] = component.$vm || component; - }); -} -function initRefs(instance, mpInstance) { - Object.defineProperty(instance, 'refs', { - get() { - const $refs = {}; - selectAllComponents(mpInstance, '.vue-ref', $refs); - const forComponents = mpInstance.selectAllComponents('.vue-ref-in-for'); - forComponents.forEach((component) => { - const ref = component.dataset.ref; - if (!$refs[ref]) { - $refs[ref] = []; - } - $refs[ref].push(component.$vm || component); - }); - return $refs; - }, - }); -} -function findVmByVueId(instance, vuePid) { - // 标准 vue3 中 没有 $children,定制了内核 - const $children = instance.$children; - // 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200) - for (let i = $children.length - 1; i >= 0; i--) { - const childVm = $children[i]; - if (childVm.$scope._$vueId === vuePid) { - return childVm; - } - } - // 反向递归查找 - let parentVm; - for (let i = $children.length - 1; i >= 0; i--) { - parentVm = findVmByVueId($children[i], vuePid); - if (parentVm) { - return parentVm; - } - } -} - const PROP_TYPES = [String, Number, Boolean, Object, Array, null]; function createObserver(name) { return function observer(newVal) { @@ -602,18 +729,6 @@ function applyOptions(componentOptions, vueOptions, initBehavior) { componentOptions.behaviors = initBehaviors(vueOptions, initBehavior); } -function getValue(obj, path) { - const parts = path.split('.'); - let key = parts[0]; - if (key.indexOf('__$n') === 0) { - //number index - key = parseInt(key.replace('__$n', '')); - } - if (parts.length === 1) { - return obj[key]; - } - return getValue(obj[key], parts.slice(1).join('.')); -} function getExtraValue(instance, dataPathsArray) { let context = instance; dataPathsArray.forEach((dataPathArray) => { @@ -635,7 +750,7 @@ function getExtraValue(instance, dataPathsArray) { vFor = dataPath.substr(3); } else { - vFor = getValue(context, dataPath); + vFor = getTarget(context, dataPath); } } if (Number.isInteger(vFor)) { @@ -647,12 +762,12 @@ function getExtraValue(instance, dataPathsArray) { else { if (isArray(vFor)) { context = vFor.find((vForItem) => { - return getValue(vForItem, propPath) === value; + return getTarget(vForItem, propPath) === value; }); } else if (isPlainObject(vFor)) { context = Object.keys(vFor).find((vForKey) => { - return getValue(vFor[vForKey], propPath) === value; + return getTarget(vFor[vForKey], propPath) === value; }); } else { @@ -660,7 +775,7 @@ function getExtraValue(instance, dataPathsArray) { } } if (valuePath) { - context = getValue(context, valuePath); + context = getTarget(context, valuePath); } } }); @@ -701,10 +816,10 @@ function processEventExtra(instance, extra, event) { } else if (dataPath.indexOf('$event.') === 0) { // $event.target.value - extraObj['$' + index] = getValue(event, dataPath.replace('$event.', '')); + extraObj['$' + index] = getTarget(event, dataPath.replace('$event.', '')); } else { - extraObj['$' + index] = getValue(instance, dataPath); + extraObj['$' + index] = getTarget(instance, dataPath); } } } @@ -849,7 +964,14 @@ function handleEvent(event) { } handler.once = true; } - ret.push(handler.apply(handlerCtx, processEventArgs(this.$vm, event, eventArray[1], eventArray[2], isCustom, methodName))); + let params = processEventArgs(this.$vm, event, eventArray[1], eventArray[2], isCustom, methodName); + params = Array.isArray(params) ? params : []; + // 参数尾部增加原始事件对象用于复杂表达式内获取额外数据 + if (/=\s*\S+\.eventParams\s*\|\|\s*\S+\[['"]event-params['"]\]/.test(handler.toString())) { + // eslint-disable-next-line no-sparse-arrays + params = params.concat([, , , , , , , , , , event]); + } + ret.push(handler.apply(handlerCtx, params)); } }); } diff --git a/packages/uni-mp-core/src/api/index.ts b/packages/uni-mp-core/src/api/index.ts index 8e69add5ffe66688ac717a9931b84eaab655f9e3..ae432637dbbfc733ef0798f15560d95d64e4c7a2 100644 --- a/packages/uni-mp-core/src/api/index.ts +++ b/packages/uni-mp-core/src/api/index.ts @@ -5,13 +5,26 @@ import { addInterceptor, removeInterceptor, } from '@dcloudio/uni-api/src/service/base/interceptor' - +import { + $on, + $off, + $once, + $emit, +} from '@dcloudio/uni-api/src/service/base/eventBus' import { promisify } from './promise' import { initWrapper } from './wrapper' import { MPProtocols } from './protocols' -const baseApis = { upx2px, addInterceptor, removeInterceptor } +const baseApis = { + $on, + $off, + $once, + $emit, + upx2px, + addInterceptor, + removeInterceptor, +} export function initUni(api: Record, protocols: MPProtocols) { const wrapper = initWrapper(protocols) diff --git a/packages/uni-mp-core/src/runtime/componentEvents.ts b/packages/uni-mp-core/src/runtime/componentEvents.ts index ab3a164912060b5fa7698fa6d611a7cf5eef602d..77a765207b29db5055d470593709e0994aaaf9f8 100644 --- a/packages/uni-mp-core/src/runtime/componentEvents.ts +++ b/packages/uni-mp-core/src/runtime/componentEvents.ts @@ -8,6 +8,7 @@ import { } from '@vue/shared' import { ComponentPublicInstance } from 'vue' import { MPComponentInstance } from './component' +import { getTarget } from './util' interface Event extends WechatMiniprogram.BaseEvent { detail: Record @@ -15,19 +16,6 @@ interface Event extends WechatMiniprogram.BaseEvent { preventDefault: () => void } -function getValue(obj: any, path: string): unknown { - const parts = path.split('.') - let key: string | number = parts[0] - if (key.indexOf('__$n') === 0) { - //number index - key = parseInt(key.replace('__$n', '')) - } - if (parts.length === 1) { - return obj[key] - } - return getValue(obj[key], parts.slice(1).join('.')) -} - function getExtraValue( instance: ComponentPublicInstance, dataPathsArray: string[] @@ -50,7 +38,7 @@ function getExtraValue( if (dataPath.indexOf('#s#') === 0) { vFor = dataPath.substr(3) } else { - vFor = getValue(context, dataPath) + vFor = getTarget(context, dataPath) } } @@ -61,11 +49,11 @@ function getExtraValue( } else { if (isArray(vFor)) { context = vFor.find((vForItem) => { - return getValue(vForItem, propPath) === value + return getTarget(vForItem, propPath) === value }) } else if (isPlainObject(vFor)) { context = Object.keys(vFor).find((vForKey) => { - return getValue(vFor[vForKey], propPath) === value + return getTarget(vFor[vForKey], propPath) === value }) } else { console.error('v-for 暂不支持循环数据:', vFor) @@ -73,7 +61,7 @@ function getExtraValue( } if (valuePath) { - context = getValue(context, valuePath) + context = getTarget(context, valuePath) } } }) @@ -116,12 +104,12 @@ function processEventExtra( } } else if (dataPath.indexOf('$event.') === 0) { // $event.target.value - extraObj['$' + index] = getValue( + extraObj['$' + index] = getTarget( event, dataPath.replace('$event.', '') ) } else { - extraObj['$' + index] = getValue(instance, dataPath) + extraObj['$' + index] = getTarget(instance, dataPath) } } } else { @@ -305,19 +293,25 @@ export function handleEvent(this: MPComponentInstance, event: Event) { } handler.once = true } - ret.push( - handler.apply( - handlerCtx, - processEventArgs( - this.$vm!, - event, - eventArray[1], - eventArray[2], - isCustom, - methodName - ) - ) + let params = processEventArgs( + this.$vm!, + event, + eventArray[1], + eventArray[2], + isCustom, + methodName ) + params = Array.isArray(params) ? params : [] + // 参数尾部增加原始事件对象用于复杂表达式内获取额外数据 + if ( + /=\s*\S+\.eventParams\s*\|\|\s*\S+\[['"]event-params['"]\]/.test( + handler.toString() + ) + ) { + // eslint-disable-next-line no-sparse-arrays + params = params.concat([, , , , , , , , , , event]) + } + ret.push(handler.apply(handlerCtx, params)) } }) } diff --git a/packages/uni-mp-core/src/runtime/componentInstance.ts b/packages/uni-mp-core/src/runtime/componentInstance/index.ts similarity index 95% rename from packages/uni-mp-core/src/runtime/componentInstance.ts rename to packages/uni-mp-core/src/runtime/componentInstance/index.ts index 74e66094421d825d3af9c96ab0dae0fdb3ae6207..783ef582bf3b022499f47a547a8f5677967c9cc3 100644 --- a/packages/uni-mp-core/src/runtime/componentInstance.ts +++ b/packages/uni-mp-core/src/runtime/componentInstance/index.ts @@ -9,8 +9,9 @@ import { } from '@vue/shared' import { ComponentPublicInstance, ComponentInternalInstance } from 'vue' -import { getEventChannel } from '../api/protocols/navigateTo' -import { MPComponentInstance } from '../index' +import { getEventChannel } from '../../api/protocols/navigateTo' +import { MPComponentInstance } from '../component' +import { getClass, getStyle, getValue } from './utils' function setModel( this: ComponentPublicInstance, @@ -185,7 +186,9 @@ export function initComponentInstance( ctx.__set_sync = setSync ctx.__get_orig = getOrig // TODO - // ctx.__get_style = getStyle + ctx.__get_value = getValue + ctx.__get_class = getClass + ctx.__get_style = getStyle ctx.__map = map } diff --git a/packages/uni-mp-core/src/runtime/componentInstance/utils.ts b/packages/uni-mp-core/src/runtime/componentInstance/utils.ts new file mode 100644 index 0000000000000000000000000000000000000000..b4b0e01b63b17047334621af82227ac749a4e3ce --- /dev/null +++ b/packages/uni-mp-core/src/runtime/componentInstance/utils.ts @@ -0,0 +1,120 @@ +import { ComponentPublicInstance } from 'vue' +import { extend, isObject, hyphenate } from '@vue/shared' +import { cache } from '@dcloudio/uni-shared' +import { getTarget } from '../util' + +export function getValue( + this: ComponentPublicInstance, + dataPath: string, + target: Record +) { + return getTarget(target || this, dataPath) +} + +export function getClass(dynamicClass: unknown, staticClass: string) { + return renderClass(staticClass, dynamicClass) +} + +export function getStyle(dynamicStyle: unknown, staticStyle: string) { + if (!dynamicStyle && !staticStyle) { + return '' + } + var dynamicStyleObj = normalizeStyleBinding(dynamicStyle) + var styleObj = staticStyle + ? extend(staticStyle, dynamicStyleObj) + : dynamicStyleObj + return Object.keys(styleObj as any) + .map(function (name) { + return hyphenate(name) + ':' + (styleObj as any)[name] + }) + .join(';') +} +function toObject(arr: unknown[]) { + var res = {} + for (var i = 0; i < arr.length; i++) { + if (arr[i]) { + extend(res, arr[i]) + } + } + return res +} + +function normalizeStyleBinding(bindingStyle: unknown) { + if (Array.isArray(bindingStyle)) { + return toObject(bindingStyle) + } + if (typeof bindingStyle === 'string') { + return parseStyleText(bindingStyle) + } + return bindingStyle +} + +var parseStyleText = cache(function parseStyleText(cssText) { + var res = {} + var listDelimiter = /;(?![^(]*\))/g + var propertyDelimiter = /:(.+)/ + cssText.split(listDelimiter).forEach(function (item) { + if (item) { + var tmp = item.split(propertyDelimiter) + tmp.length > 1 && ((res as any)[tmp[0].trim()] = tmp[1].trim()) + } + }) + return res +}) + +function isDef(v: unknown) { + return v !== undefined && v !== null +} + +function renderClass(staticClass: string, dynamicClass: unknown) { + if (isDef(staticClass) || isDef(dynamicClass)) { + return concat(staticClass, stringifyClass(dynamicClass)) + } + /* istanbul ignore next */ + return '' +} + +function concat(a?: string, b?: string) { + return a ? (b ? a + ' ' + b : a) : b || '' +} + +function stringifyClass(value: unknown) { + if (Array.isArray(value)) { + return stringifyArray(value) + } + if (isObject(value)) { + return stringifyObject(value) + } + if (typeof value === 'string') { + return value + } + /* istanbul ignore next */ + return '' +} + +function stringifyArray(value: unknown[]) { + var res = '' + var stringified + for (var i = 0, l = value.length; i < l; i++) { + if (isDef((stringified = stringifyClass(value[i]))) && stringified !== '') { + if (res) { + res += ' ' + } + res += stringified + } + } + return res +} + +function stringifyObject(value: Record) { + var res = '' + for (var key in value) { + if (value[key]) { + if (res) { + res += ' ' + } + res += key + } + } + return res +} diff --git a/packages/uni-mp-core/src/runtime/util.ts b/packages/uni-mp-core/src/runtime/util.ts index 9004fae08c9e17028caf0553c0e9bce067c0798d..0b35f1196d77c1048d0e20b4dff8c34357ef2d23 100644 --- a/packages/uni-mp-core/src/runtime/util.ts +++ b/packages/uni-mp-core/src/runtime/util.ts @@ -124,3 +124,19 @@ export function findVmByVueId( } } } + +export function getTarget(obj: any, path: string): unknown { + const parts = path.split('.') + let key: number | string = parts[0] + if (key.indexOf('__$n') === 0) { + //number index + key = parseInt(key.replace('__$n', '')) + } + if (!obj) { + obj = {} + } + if (parts.length === 1) { + return obj[key] + } + return getTarget(obj[key], parts.slice(1).join('.')) +} diff --git a/packages/uni-mp-qq/dist/uni.api.esm.js b/packages/uni-mp-qq/dist/uni.api.esm.js index 1e4369dbf8627a5e5e446b07a693b238c7fa946a..3a0dc8318edf0a97ddf500e0be10bcb00acab26c 100644 --- a/packages/uni-mp-qq/dist/uni.api.esm.js +++ b/packages/uni-mp-qq/dist/uni.api.esm.js @@ -462,6 +462,114 @@ const removeInterceptor = defineSyncApi(API_REMOVE_INTERCEPTOR, (method, interce } }, RemoveInterceptorProtocol); +const API_ON = '$on'; +const OnProtocol = [ + { + name: 'event', + type: String, + required: true, + }, + { + name: 'callback', + type: Function, + required: true, + }, +]; +const API_ONCE = '$once'; +const OnceProtocol = OnProtocol; +const API_OFF = '$off'; +const OffProtocol = [ + { + name: 'event', + type: [String, Array], + }, + { + name: 'callback', + type: Function, + }, +]; +const API_EMIT = '$emit'; +const EmitProtocol = [ + { + name: 'event', + type: String, + required: true, + }, +]; + +const E = function () { + // Keep this empty so it's easier to inherit from + // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3) +}; +E.prototype = { + on: function (name, callback, ctx) { + var e = this.e || (this.e = {}); + (e[name] || (e[name] = [])).push({ + fn: callback, + ctx: ctx, + }); + return this; + }, + once: function (name, callback, ctx) { + var self = this; + function listener() { + self.off(name, listener); + callback.apply(ctx, arguments); + } + listener._ = callback; + return this.on(name, listener, ctx); + }, + emit: function (name) { + var data = [].slice.call(arguments, 1); + var evtArr = ((this.e || (this.e = {}))[name] || []).slice(); + var i = 0; + var len = evtArr.length; + for (i; i < len; i++) { + evtArr[i].fn.apply(evtArr[i].ctx, data); + } + return this; + }, + off: function (name, callback) { + var e = this.e || (this.e = {}); + var evts = e[name]; + var liveEvents = []; + if (evts && callback) { + for (var i = 0, len = evts.length; i < len; i++) { + if (evts[i].fn !== callback && evts[i].fn._ !== callback) + liveEvents.push(evts[i]); + } + } + // Remove event from queue to prevent memory leak + // Suggested by https://github.com/lazd + // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910 + liveEvents.length ? (e[name] = liveEvents) : delete e[name]; + return this; + }, +}; +var Emitter = E; + +const emitter = new Emitter(); +const $on = defineSyncApi(API_ON, (name, callback) => { + emitter.on(name, callback); + return () => emitter.off(name, callback); +}, OnProtocol); +const $once = defineSyncApi(API_ONCE, (name, callback) => { + emitter.once(name, callback); + return () => emitter.off(name, callback); +}, OnceProtocol); +const $off = defineSyncApi(API_OFF, (name, callback) => { + if (!name) { + emitter.e = {}; + return; + } + if (!Array.isArray(name)) + name = [name]; + name.forEach((n) => emitter.off(n, callback)); +}, OffProtocol); +const $emit = defineSyncApi(API_EMIT, (name, ...args) => { + emitter.emit(name, ...args); +}, EmitProtocol); + const SYNC_API_RE = /^\$|sendNativeEvent|restoreGlobal|getCurrentSubNVue|getMenuButtonBoundingClientRect|^report|interceptors|Interceptor$|getSubNVueById|requireNativePlugin|upx2px|hideKeyboard|canIUse|^create|Sync$|Manager$|base64ToArrayBuffer|arrayBufferToBase64/; const CONTEXT_API_RE = /^create|Manager$/; // Context例外情况 @@ -606,7 +714,15 @@ function initWrapper(protocols) { }; } -const baseApis = { upx2px, addInterceptor, removeInterceptor }; +const baseApis = { + $on, + $off, + $once, + $emit, + upx2px, + addInterceptor, + removeInterceptor, +}; function initUni(api, protocols) { const wrapper = initWrapper(protocols); const UniProxyHandlers = { diff --git a/packages/uni-mp-qq/dist/uni.mp.esm.js b/packages/uni-mp-qq/dist/uni.mp.esm.js index 5ecb45d1f1644d8b68eaeb4d38fbfa80c03c1ab9..2387513ad6165e9de5bd544775644afe569e3245 100644 --- a/packages/uni-mp-qq/dist/uni.mp.esm.js +++ b/packages/uni-mp-qq/dist/uni.mp.esm.js @@ -1,4 +1,4 @@ -import { isPlainObject, isArray, hasOwn, toNumber, isObject, isFunction, extend, NOOP, camelize } from '@vue/shared'; +import { isPlainObject, hasOwn, isArray, extend, hyphenate, isObject, toNumber, isFunction, NOOP, camelize } from '@vue/shared'; const encode = encodeURIComponent; function stringifyQuery(obj, encodeStr = encode) { @@ -19,6 +19,14 @@ function stringifyQuery(obj, encodeStr = encode) { : null; return res ? `?${res}` : ''; } + +function cache(fn) { + const cache = Object.create(null); + return (str) => { + const hit = cache[str]; + return hit || (cache[str] = fn(str)); + }; +} const invokeArrayFns = (fns, arg) => { let ret; for (let i = 0; i < fns.length; i++) { @@ -120,6 +128,202 @@ function getEventChannel(id) { return eventChannelStack.shift(); } +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) => { + const ref = component.dataset.ref; + $refs[ref] = component.$vm || component; + }); +} +function initRefs(instance, mpInstance) { + Object.defineProperty(instance, 'refs', { + get() { + const $refs = {}; + selectAllComponents(mpInstance, '.vue-ref', $refs); + const forComponents = mpInstance.selectAllComponents('.vue-ref-in-for'); + forComponents.forEach((component) => { + const ref = component.dataset.ref; + 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; + } + } +} +function getTarget(obj, path) { + const parts = path.split('.'); + let key = parts[0]; + if (key.indexOf('__$n') === 0) { + //number index + key = parseInt(key.replace('__$n', '')); + } + if (!obj) { + obj = {}; + } + if (parts.length === 1) { + return obj[key]; + } + return getTarget(obj[key], parts.slice(1).join('.')); +} + +function getValue(dataPath, target) { + return getTarget(target || this, dataPath); +} +function getClass(dynamicClass, staticClass) { + return renderClass(staticClass, dynamicClass); +} +function getStyle(dynamicStyle, staticStyle) { + if (!dynamicStyle && !staticStyle) { + return ''; + } + var dynamicStyleObj = normalizeStyleBinding(dynamicStyle); + var styleObj = staticStyle + ? extend(staticStyle, dynamicStyleObj) + : dynamicStyleObj; + return Object.keys(styleObj) + .map(function (name) { + return hyphenate(name) + ':' + styleObj[name]; + }) + .join(';'); +} +function toObject(arr) { + var res = {}; + for (var i = 0; i < arr.length; i++) { + if (arr[i]) { + extend(res, arr[i]); + } + } + return res; +} +function normalizeStyleBinding(bindingStyle) { + if (Array.isArray(bindingStyle)) { + return toObject(bindingStyle); + } + if (typeof bindingStyle === 'string') { + return parseStyleText(bindingStyle); + } + return bindingStyle; +} +var parseStyleText = cache(function parseStyleText(cssText) { + var res = {}; + var listDelimiter = /;(?![^(]*\))/g; + var propertyDelimiter = /:(.+)/; + cssText.split(listDelimiter).forEach(function (item) { + if (item) { + var tmp = item.split(propertyDelimiter); + tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim()); + } + }); + return res; +}); +function isDef(v) { + return v !== undefined && v !== null; +} +function renderClass(staticClass, dynamicClass) { + if (isDef(staticClass) || isDef(dynamicClass)) { + return concat(staticClass, stringifyClass(dynamicClass)); + } + /* istanbul ignore next */ + return ''; +} +function concat(a, b) { + return a ? (b ? a + ' ' + b : a) : b || ''; +} +function stringifyClass(value) { + if (Array.isArray(value)) { + return stringifyArray(value); + } + if (isObject(value)) { + return stringifyObject(value); + } + if (typeof value === 'string') { + return value; + } + /* istanbul ignore next */ + return ''; +} +function stringifyArray(value) { + var res = ''; + var stringified; + for (var i = 0, l = value.length; i < l; i++) { + if (isDef((stringified = stringifyClass(value[i]))) && stringified !== '') { + if (res) { + res += ' '; + } + res += stringified; + } + } + return res; +} +function stringifyObject(value) { + var res = ''; + for (var key in value) { + if (value[key]) { + if (res) { + res += ' '; + } + res += key; + } + } + return res; +} + function setModel(target, key, value, modifiers) { if (isArray(modifiers)) { if (modifiers.indexOf('trim') !== -1) { @@ -229,7 +433,9 @@ function initComponentInstance(instance, options) { ctx.__set_sync = setSync; ctx.__get_orig = getOrig; // TODO - // ctx.__get_style = getStyle + ctx.__get_value = getValue; + ctx.__get_class = getClass; + ctx.__get_style = getStyle; ctx.__map = map; } function initMocks(instance, mpInstance, mocks) { @@ -356,85 +562,6 @@ function initCreateApp(parseAppOptions) { }; } -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) => { - const ref = component.dataset.ref; - $refs[ref] = component.$vm || component; - }); -} -function initRefs(instance, mpInstance) { - Object.defineProperty(instance, 'refs', { - get() { - const $refs = {}; - selectAllComponents(mpInstance, '.vue-ref', $refs); - const forComponents = mpInstance.selectAllComponents('.vue-ref-in-for'); - forComponents.forEach((component) => { - const ref = component.dataset.ref; - if (!$refs[ref]) { - $refs[ref] = []; - } - $refs[ref].push(component.$vm || component); - }); - return $refs; - }, - }); -} -function findVmByVueId(instance, vuePid) { - // 标准 vue3 中 没有 $children,定制了内核 - const $children = instance.$children; - // 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200) - for (let i = $children.length - 1; i >= 0; i--) { - const childVm = $children[i]; - if (childVm.$scope._$vueId === vuePid) { - return childVm; - } - } - // 反向递归查找 - let parentVm; - for (let i = $children.length - 1; i >= 0; i--) { - parentVm = findVmByVueId($children[i], vuePid); - if (parentVm) { - return parentVm; - } - } -} - const PROP_TYPES = [String, Number, Boolean, Object, Array, null]; function createObserver(name) { return function observer(newVal) { @@ -591,18 +718,6 @@ function applyOptions(componentOptions, vueOptions, initBehavior) { componentOptions.behaviors = initBehaviors(vueOptions, initBehavior); } -function getValue(obj, path) { - const parts = path.split('.'); - let key = parts[0]; - if (key.indexOf('__$n') === 0) { - //number index - key = parseInt(key.replace('__$n', '')); - } - if (parts.length === 1) { - return obj[key]; - } - return getValue(obj[key], parts.slice(1).join('.')); -} function getExtraValue(instance, dataPathsArray) { let context = instance; dataPathsArray.forEach((dataPathArray) => { @@ -624,7 +739,7 @@ function getExtraValue(instance, dataPathsArray) { vFor = dataPath.substr(3); } else { - vFor = getValue(context, dataPath); + vFor = getTarget(context, dataPath); } } if (Number.isInteger(vFor)) { @@ -636,12 +751,12 @@ function getExtraValue(instance, dataPathsArray) { else { if (isArray(vFor)) { context = vFor.find((vForItem) => { - return getValue(vForItem, propPath) === value; + return getTarget(vForItem, propPath) === value; }); } else if (isPlainObject(vFor)) { context = Object.keys(vFor).find((vForKey) => { - return getValue(vFor[vForKey], propPath) === value; + return getTarget(vFor[vForKey], propPath) === value; }); } else { @@ -649,7 +764,7 @@ function getExtraValue(instance, dataPathsArray) { } } if (valuePath) { - context = getValue(context, valuePath); + context = getTarget(context, valuePath); } } }); @@ -690,10 +805,10 @@ function processEventExtra(instance, extra, event) { } else if (dataPath.indexOf('$event.') === 0) { // $event.target.value - extraObj['$' + index] = getValue(event, dataPath.replace('$event.', '')); + extraObj['$' + index] = getTarget(event, dataPath.replace('$event.', '')); } else { - extraObj['$' + index] = getValue(instance, dataPath); + extraObj['$' + index] = getTarget(instance, dataPath); } } } @@ -830,7 +945,14 @@ function handleEvent(event) { } handler.once = true; } - ret.push(handler.apply(handlerCtx, processEventArgs(this.$vm, event, eventArray[1], eventArray[2], isCustom, methodName))); + let params = processEventArgs(this.$vm, event, eventArray[1], eventArray[2], isCustom, methodName); + params = Array.isArray(params) ? params : []; + // 参数尾部增加原始事件对象用于复杂表达式内获取额外数据 + if (/=\s*\S+\.eventParams\s*\|\|\s*\S+\[['"]event-params['"]\]/.test(handler.toString())) { + // eslint-disable-next-line no-sparse-arrays + params = params.concat([, , , , , , , , , , event]); + } + ret.push(handler.apply(handlerCtx, params)); } }); } diff --git a/packages/uni-mp-toutiao/dist/uni.api.esm.js b/packages/uni-mp-toutiao/dist/uni.api.esm.js index 874c531b77b1bd8518cf14f0e79b9a5af901a44c..1641db8f3c4e7b6ca76970a3effb1e5bf4482c15 100644 --- a/packages/uni-mp-toutiao/dist/uni.api.esm.js +++ b/packages/uni-mp-toutiao/dist/uni.api.esm.js @@ -462,6 +462,114 @@ const removeInterceptor = defineSyncApi(API_REMOVE_INTERCEPTOR, (method, interce } }, RemoveInterceptorProtocol); +const API_ON = '$on'; +const OnProtocol = [ + { + name: 'event', + type: String, + required: true, + }, + { + name: 'callback', + type: Function, + required: true, + }, +]; +const API_ONCE = '$once'; +const OnceProtocol = OnProtocol; +const API_OFF = '$off'; +const OffProtocol = [ + { + name: 'event', + type: [String, Array], + }, + { + name: 'callback', + type: Function, + }, +]; +const API_EMIT = '$emit'; +const EmitProtocol = [ + { + name: 'event', + type: String, + required: true, + }, +]; + +const E = function () { + // Keep this empty so it's easier to inherit from + // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3) +}; +E.prototype = { + on: function (name, callback, ctx) { + var e = this.e || (this.e = {}); + (e[name] || (e[name] = [])).push({ + fn: callback, + ctx: ctx, + }); + return this; + }, + once: function (name, callback, ctx) { + var self = this; + function listener() { + self.off(name, listener); + callback.apply(ctx, arguments); + } + listener._ = callback; + return this.on(name, listener, ctx); + }, + emit: function (name) { + var data = [].slice.call(arguments, 1); + var evtArr = ((this.e || (this.e = {}))[name] || []).slice(); + var i = 0; + var len = evtArr.length; + for (i; i < len; i++) { + evtArr[i].fn.apply(evtArr[i].ctx, data); + } + return this; + }, + off: function (name, callback) { + var e = this.e || (this.e = {}); + var evts = e[name]; + var liveEvents = []; + if (evts && callback) { + for (var i = 0, len = evts.length; i < len; i++) { + if (evts[i].fn !== callback && evts[i].fn._ !== callback) + liveEvents.push(evts[i]); + } + } + // Remove event from queue to prevent memory leak + // Suggested by https://github.com/lazd + // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910 + liveEvents.length ? (e[name] = liveEvents) : delete e[name]; + return this; + }, +}; +var Emitter = E; + +const emitter = new Emitter(); +const $on = defineSyncApi(API_ON, (name, callback) => { + emitter.on(name, callback); + return () => emitter.off(name, callback); +}, OnProtocol); +const $once = defineSyncApi(API_ONCE, (name, callback) => { + emitter.once(name, callback); + return () => emitter.off(name, callback); +}, OnceProtocol); +const $off = defineSyncApi(API_OFF, (name, callback) => { + if (!name) { + emitter.e = {}; + return; + } + if (!Array.isArray(name)) + name = [name]; + name.forEach((n) => emitter.off(n, callback)); +}, OffProtocol); +const $emit = defineSyncApi(API_EMIT, (name, ...args) => { + emitter.emit(name, ...args); +}, EmitProtocol); + const SYNC_API_RE = /^\$|sendNativeEvent|restoreGlobal|getCurrentSubNVue|getMenuButtonBoundingClientRect|^report|interceptors|Interceptor$|getSubNVueById|requireNativePlugin|upx2px|hideKeyboard|canIUse|^create|Sync$|Manager$|base64ToArrayBuffer|arrayBufferToBase64/; const CONTEXT_API_RE = /^create|Manager$/; // Context例外情况 @@ -606,7 +714,15 @@ function initWrapper(protocols) { }; } -const baseApis = { upx2px, addInterceptor, removeInterceptor }; +const baseApis = { + $on, + $off, + $once, + $emit, + upx2px, + addInterceptor, + removeInterceptor, +}; function initUni(api, protocols) { const wrapper = initWrapper(protocols); const UniProxyHandlers = { diff --git a/packages/uni-mp-toutiao/dist/uni.mp.esm.js b/packages/uni-mp-toutiao/dist/uni.mp.esm.js index a10aceaa4240560569375cf29f9df118c7639afc..95f25dfa06778150505f56845b57c49d80c18057 100644 --- a/packages/uni-mp-toutiao/dist/uni.mp.esm.js +++ b/packages/uni-mp-toutiao/dist/uni.mp.esm.js @@ -1,4 +1,4 @@ -import { isPlainObject, isArray, hasOwn, toNumber, isObject, isFunction, extend, NOOP, camelize } from '@vue/shared'; +import { isPlainObject, hasOwn, isArray, extend, hyphenate, isObject, toNumber, isFunction, NOOP, camelize } from '@vue/shared'; const encode = encodeURIComponent; function stringifyQuery(obj, encodeStr = encode) { @@ -19,6 +19,14 @@ function stringifyQuery(obj, encodeStr = encode) { : null; return res ? `?${res}` : ''; } + +function cache(fn) { + const cache = Object.create(null); + return (str) => { + const hit = cache[str]; + return hit || (cache[str] = fn(str)); + }; +} const invokeArrayFns = (fns, arg) => { let ret; for (let i = 0; i < fns.length; i++) { @@ -120,6 +128,202 @@ function getEventChannel(id) { return eventChannelStack.shift(); } +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) => { + const ref = component.dataset.ref; + $refs[ref] = component.$vm || component; + }); +} +function initRefs(instance, mpInstance) { + Object.defineProperty(instance, 'refs', { + get() { + const $refs = {}; + selectAllComponents(mpInstance, '.vue-ref', $refs); + const forComponents = mpInstance.selectAllComponents('.vue-ref-in-for'); + forComponents.forEach((component) => { + const ref = component.dataset.ref; + 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; + } + } +} +function getTarget(obj, path) { + const parts = path.split('.'); + let key = parts[0]; + if (key.indexOf('__$n') === 0) { + //number index + key = parseInt(key.replace('__$n', '')); + } + if (!obj) { + obj = {}; + } + if (parts.length === 1) { + return obj[key]; + } + return getTarget(obj[key], parts.slice(1).join('.')); +} + +function getValue(dataPath, target) { + return getTarget(target || this, dataPath); +} +function getClass(dynamicClass, staticClass) { + return renderClass(staticClass, dynamicClass); +} +function getStyle(dynamicStyle, staticStyle) { + if (!dynamicStyle && !staticStyle) { + return ''; + } + var dynamicStyleObj = normalizeStyleBinding(dynamicStyle); + var styleObj = staticStyle + ? extend(staticStyle, dynamicStyleObj) + : dynamicStyleObj; + return Object.keys(styleObj) + .map(function (name) { + return hyphenate(name) + ':' + styleObj[name]; + }) + .join(';'); +} +function toObject(arr) { + var res = {}; + for (var i = 0; i < arr.length; i++) { + if (arr[i]) { + extend(res, arr[i]); + } + } + return res; +} +function normalizeStyleBinding(bindingStyle) { + if (Array.isArray(bindingStyle)) { + return toObject(bindingStyle); + } + if (typeof bindingStyle === 'string') { + return parseStyleText(bindingStyle); + } + return bindingStyle; +} +var parseStyleText = cache(function parseStyleText(cssText) { + var res = {}; + var listDelimiter = /;(?![^(]*\))/g; + var propertyDelimiter = /:(.+)/; + cssText.split(listDelimiter).forEach(function (item) { + if (item) { + var tmp = item.split(propertyDelimiter); + tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim()); + } + }); + return res; +}); +function isDef(v) { + return v !== undefined && v !== null; +} +function renderClass(staticClass, dynamicClass) { + if (isDef(staticClass) || isDef(dynamicClass)) { + return concat(staticClass, stringifyClass(dynamicClass)); + } + /* istanbul ignore next */ + return ''; +} +function concat(a, b) { + return a ? (b ? a + ' ' + b : a) : b || ''; +} +function stringifyClass(value) { + if (Array.isArray(value)) { + return stringifyArray(value); + } + if (isObject(value)) { + return stringifyObject(value); + } + if (typeof value === 'string') { + return value; + } + /* istanbul ignore next */ + return ''; +} +function stringifyArray(value) { + var res = ''; + var stringified; + for (var i = 0, l = value.length; i < l; i++) { + if (isDef((stringified = stringifyClass(value[i]))) && stringified !== '') { + if (res) { + res += ' '; + } + res += stringified; + } + } + return res; +} +function stringifyObject(value) { + var res = ''; + for (var key in value) { + if (value[key]) { + if (res) { + res += ' '; + } + res += key; + } + } + return res; +} + function setModel(target, key, value, modifiers) { if (isArray(modifiers)) { if (modifiers.indexOf('trim') !== -1) { @@ -229,7 +433,9 @@ function initComponentInstance(instance, options) { ctx.__set_sync = setSync; ctx.__get_orig = getOrig; // TODO - // ctx.__get_style = getStyle + ctx.__get_value = getValue; + ctx.__get_class = getClass; + ctx.__get_style = getStyle; ctx.__map = map; } function initMocks(instance, mpInstance, mocks) { @@ -359,85 +565,6 @@ function initCreateApp(parseAppOptions) { }; } -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) => { - const ref = component.dataset.ref; - $refs[ref] = component.$vm || component; - }); -} -function initRefs(instance, mpInstance) { - Object.defineProperty(instance, 'refs', { - get() { - const $refs = {}; - selectAllComponents(mpInstance, '.vue-ref', $refs); - const forComponents = mpInstance.selectAllComponents('.vue-ref-in-for'); - forComponents.forEach((component) => { - const ref = component.dataset.ref; - if (!$refs[ref]) { - $refs[ref] = []; - } - $refs[ref].push(component.$vm || component); - }); - return $refs; - }, - }); -} -function findVmByVueId(instance, vuePid) { - // 标准 vue3 中 没有 $children,定制了内核 - const $children = instance.$children; - // 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200) - for (let i = $children.length - 1; i >= 0; i--) { - const childVm = $children[i]; - if (childVm.$scope._$vueId === vuePid) { - return childVm; - } - } - // 反向递归查找 - let parentVm; - for (let i = $children.length - 1; i >= 0; i--) { - parentVm = findVmByVueId($children[i], vuePid); - if (parentVm) { - return parentVm; - } - } -} - const PROP_TYPES = [String, Number, Boolean, Object, Array, null]; function createObserver(name) { return function observer(newVal) { @@ -600,18 +727,6 @@ function applyOptions(componentOptions, vueOptions, initBehavior) { componentOptions.behaviors = initBehaviors(vueOptions, initBehavior); } -function getValue(obj, path) { - const parts = path.split('.'); - let key = parts[0]; - if (key.indexOf('__$n') === 0) { - //number index - key = parseInt(key.replace('__$n', '')); - } - if (parts.length === 1) { - return obj[key]; - } - return getValue(obj[key], parts.slice(1).join('.')); -} function getExtraValue(instance, dataPathsArray) { let context = instance; dataPathsArray.forEach((dataPathArray) => { @@ -633,7 +748,7 @@ function getExtraValue(instance, dataPathsArray) { vFor = dataPath.substr(3); } else { - vFor = getValue(context, dataPath); + vFor = getTarget(context, dataPath); } } if (Number.isInteger(vFor)) { @@ -645,12 +760,12 @@ function getExtraValue(instance, dataPathsArray) { else { if (isArray(vFor)) { context = vFor.find((vForItem) => { - return getValue(vForItem, propPath) === value; + return getTarget(vForItem, propPath) === value; }); } else if (isPlainObject(vFor)) { context = Object.keys(vFor).find((vForKey) => { - return getValue(vFor[vForKey], propPath) === value; + return getTarget(vFor[vForKey], propPath) === value; }); } else { @@ -658,7 +773,7 @@ function getExtraValue(instance, dataPathsArray) { } } if (valuePath) { - context = getValue(context, valuePath); + context = getTarget(context, valuePath); } } }); @@ -699,10 +814,10 @@ function processEventExtra(instance, extra, event) { } else if (dataPath.indexOf('$event.') === 0) { // $event.target.value - extraObj['$' + index] = getValue(event, dataPath.replace('$event.', '')); + extraObj['$' + index] = getTarget(event, dataPath.replace('$event.', '')); } else { - extraObj['$' + index] = getValue(instance, dataPath); + extraObj['$' + index] = getTarget(instance, dataPath); } } } @@ -839,7 +954,14 @@ function handleEvent(event) { } handler.once = true; } - ret.push(handler.apply(handlerCtx, processEventArgs(this.$vm, event, eventArray[1], eventArray[2], isCustom, methodName))); + let params = processEventArgs(this.$vm, event, eventArray[1], eventArray[2], isCustom, methodName); + params = Array.isArray(params) ? params : []; + // 参数尾部增加原始事件对象用于复杂表达式内获取额外数据 + if (/=\s*\S+\.eventParams\s*\|\|\s*\S+\[['"]event-params['"]\]/.test(handler.toString())) { + // eslint-disable-next-line no-sparse-arrays + params = params.concat([, , , , , , , , , , event]); + } + ret.push(handler.apply(handlerCtx, params)); } }); } diff --git a/packages/uni-mp-weixin/dist/uni.api.esm.js b/packages/uni-mp-weixin/dist/uni.api.esm.js index 306f39d4c75d9648db4beeafbe46887197b21bac..efaf972f558b49a7597439f8744a17a04eeabf97 100644 --- a/packages/uni-mp-weixin/dist/uni.api.esm.js +++ b/packages/uni-mp-weixin/dist/uni.api.esm.js @@ -426,6 +426,114 @@ const removeInterceptor = defineSyncApi(API_REMOVE_INTERCEPTOR, (method, interce } }, RemoveInterceptorProtocol); +const API_ON = '$on'; +const OnProtocol = [ + { + name: 'event', + type: String, + required: true, + }, + { + name: 'callback', + type: Function, + required: true, + }, +]; +const API_ONCE = '$once'; +const OnceProtocol = OnProtocol; +const API_OFF = '$off'; +const OffProtocol = [ + { + name: 'event', + type: [String, Array], + }, + { + name: 'callback', + type: Function, + }, +]; +const API_EMIT = '$emit'; +const EmitProtocol = [ + { + name: 'event', + type: String, + required: true, + }, +]; + +const E = function () { + // Keep this empty so it's easier to inherit from + // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3) +}; +E.prototype = { + on: function (name, callback, ctx) { + var e = this.e || (this.e = {}); + (e[name] || (e[name] = [])).push({ + fn: callback, + ctx: ctx, + }); + return this; + }, + once: function (name, callback, ctx) { + var self = this; + function listener() { + self.off(name, listener); + callback.apply(ctx, arguments); + } + listener._ = callback; + return this.on(name, listener, ctx); + }, + emit: function (name) { + var data = [].slice.call(arguments, 1); + var evtArr = ((this.e || (this.e = {}))[name] || []).slice(); + var i = 0; + var len = evtArr.length; + for (i; i < len; i++) { + evtArr[i].fn.apply(evtArr[i].ctx, data); + } + return this; + }, + off: function (name, callback) { + var e = this.e || (this.e = {}); + var evts = e[name]; + var liveEvents = []; + if (evts && callback) { + for (var i = 0, len = evts.length; i < len; i++) { + if (evts[i].fn !== callback && evts[i].fn._ !== callback) + liveEvents.push(evts[i]); + } + } + // Remove event from queue to prevent memory leak + // Suggested by https://github.com/lazd + // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910 + liveEvents.length ? (e[name] = liveEvents) : delete e[name]; + return this; + }, +}; +var Emitter = E; + +const emitter = new Emitter(); +const $on = defineSyncApi(API_ON, (name, callback) => { + emitter.on(name, callback); + return () => emitter.off(name, callback); +}, OnProtocol); +const $once = defineSyncApi(API_ONCE, (name, callback) => { + emitter.once(name, callback); + return () => emitter.off(name, callback); +}, OnceProtocol); +const $off = defineSyncApi(API_OFF, (name, callback) => { + if (!name) { + emitter.e = {}; + return; + } + if (!Array.isArray(name)) + name = [name]; + name.forEach((n) => emitter.off(n, callback)); +}, OffProtocol); +const $emit = defineSyncApi(API_EMIT, (name, ...args) => { + emitter.emit(name, ...args); +}, EmitProtocol); + const SYNC_API_RE = /^\$|sendNativeEvent|restoreGlobal|getCurrentSubNVue|getMenuButtonBoundingClientRect|^report|interceptors|Interceptor$|getSubNVueById|requireNativePlugin|upx2px|hideKeyboard|canIUse|^create|Sync$|Manager$|base64ToArrayBuffer|arrayBufferToBase64/; const CONTEXT_API_RE = /^create|Manager$/; // Context例外情况 @@ -570,7 +678,15 @@ function initWrapper(protocols) { }; } -const baseApis = { upx2px, addInterceptor, removeInterceptor }; +const baseApis = { + $on, + $off, + $once, + $emit, + upx2px, + addInterceptor, + removeInterceptor, +}; function initUni(api, protocols) { const wrapper = initWrapper(protocols); const UniProxyHandlers = { diff --git a/packages/uni-mp-weixin/dist/uni.mp.esm.js b/packages/uni-mp-weixin/dist/uni.mp.esm.js index 88f15a1e4240966fd2bbad4a0f59c50729cb0097..e2744e4c44dfab82f7baef569dfe647a9f58185e 100644 --- a/packages/uni-mp-weixin/dist/uni.mp.esm.js +++ b/packages/uni-mp-weixin/dist/uni.mp.esm.js @@ -1,4 +1,4 @@ -import { isPlainObject, isArray, hasOwn, toNumber, isObject, isFunction, extend, NOOP, camelize } from '@vue/shared'; +import { isPlainObject, hasOwn, isArray, extend, hyphenate, isObject, toNumber, isFunction, NOOP, camelize } from '@vue/shared'; const encode = encodeURIComponent; function stringifyQuery(obj, encodeStr = encode) { @@ -19,6 +19,14 @@ function stringifyQuery(obj, encodeStr = encode) { : null; return res ? `?${res}` : ''; } + +function cache(fn) { + const cache = Object.create(null); + return (str) => { + const hit = cache[str]; + return hit || (cache[str] = fn(str)); + }; +} const invokeArrayFns = (fns, arg) => { let ret; for (let i = 0; i < fns.length; i++) { @@ -57,6 +65,211 @@ function getEventChannel(id) { return eventChannelStack.shift(); } +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) => { + const ref = component.dataset.ref; + $refs[ref] = component.$vm || component; + { + if (component.dataset.vueGeneric === 'scoped') { + component + .selectAllComponents('.scoped-ref') + .forEach((scopedComponent) => { + selectAllComponents(scopedComponent, selector, $refs); + }); + } + } + }); +} +function initRefs(instance, mpInstance) { + Object.defineProperty(instance, 'refs', { + get() { + const $refs = {}; + selectAllComponents(mpInstance, '.vue-ref', $refs); + const forComponents = mpInstance.selectAllComponents('.vue-ref-in-for'); + forComponents.forEach((component) => { + const ref = component.dataset.ref; + 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; + } + } +} +function getTarget(obj, path) { + const parts = path.split('.'); + let key = parts[0]; + if (key.indexOf('__$n') === 0) { + //number index + key = parseInt(key.replace('__$n', '')); + } + if (!obj) { + obj = {}; + } + if (parts.length === 1) { + return obj[key]; + } + return getTarget(obj[key], parts.slice(1).join('.')); +} + +function getValue(dataPath, target) { + return getTarget(target || this, dataPath); +} +function getClass(dynamicClass, staticClass) { + return renderClass(staticClass, dynamicClass); +} +function getStyle(dynamicStyle, staticStyle) { + if (!dynamicStyle && !staticStyle) { + return ''; + } + var dynamicStyleObj = normalizeStyleBinding(dynamicStyle); + var styleObj = staticStyle + ? extend(staticStyle, dynamicStyleObj) + : dynamicStyleObj; + return Object.keys(styleObj) + .map(function (name) { + return hyphenate(name) + ':' + styleObj[name]; + }) + .join(';'); +} +function toObject(arr) { + var res = {}; + for (var i = 0; i < arr.length; i++) { + if (arr[i]) { + extend(res, arr[i]); + } + } + return res; +} +function normalizeStyleBinding(bindingStyle) { + if (Array.isArray(bindingStyle)) { + return toObject(bindingStyle); + } + if (typeof bindingStyle === 'string') { + return parseStyleText(bindingStyle); + } + return bindingStyle; +} +var parseStyleText = cache(function parseStyleText(cssText) { + var res = {}; + var listDelimiter = /;(?![^(]*\))/g; + var propertyDelimiter = /:(.+)/; + cssText.split(listDelimiter).forEach(function (item) { + if (item) { + var tmp = item.split(propertyDelimiter); + tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim()); + } + }); + return res; +}); +function isDef(v) { + return v !== undefined && v !== null; +} +function renderClass(staticClass, dynamicClass) { + if (isDef(staticClass) || isDef(dynamicClass)) { + return concat(staticClass, stringifyClass(dynamicClass)); + } + /* istanbul ignore next */ + return ''; +} +function concat(a, b) { + return a ? (b ? a + ' ' + b : a) : b || ''; +} +function stringifyClass(value) { + if (Array.isArray(value)) { + return stringifyArray(value); + } + if (isObject(value)) { + return stringifyObject(value); + } + if (typeof value === 'string') { + return value; + } + /* istanbul ignore next */ + return ''; +} +function stringifyArray(value) { + var res = ''; + var stringified; + for (var i = 0, l = value.length; i < l; i++) { + if (isDef((stringified = stringifyClass(value[i]))) && stringified !== '') { + if (res) { + res += ' '; + } + res += stringified; + } + } + return res; +} +function stringifyObject(value) { + var res = ''; + for (var key in value) { + if (value[key]) { + if (res) { + res += ' '; + } + res += key; + } + } + return res; +} + function setModel(target, key, value, modifiers) { if (isArray(modifiers)) { if (modifiers.indexOf('trim') !== -1) { @@ -166,7 +379,9 @@ function initComponentInstance(instance, options) { ctx.__set_sync = setSync; ctx.__get_orig = getOrig; // TODO - // ctx.__get_style = getStyle + ctx.__get_value = getValue; + ctx.__get_class = getClass; + ctx.__get_style = getStyle; ctx.__map = map; } function initMocks(instance, mpInstance, mocks) { @@ -293,94 +508,6 @@ function initCreateApp(parseAppOptions) { }; } -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) => { - const ref = component.dataset.ref; - $refs[ref] = component.$vm || component; - { - if (component.dataset.vueGeneric === 'scoped') { - component - .selectAllComponents('.scoped-ref') - .forEach((scopedComponent) => { - selectAllComponents(scopedComponent, selector, $refs); - }); - } - } - }); -} -function initRefs(instance, mpInstance) { - Object.defineProperty(instance, 'refs', { - get() { - const $refs = {}; - selectAllComponents(mpInstance, '.vue-ref', $refs); - const forComponents = mpInstance.selectAllComponents('.vue-ref-in-for'); - forComponents.forEach((component) => { - const ref = component.dataset.ref; - if (!$refs[ref]) { - $refs[ref] = []; - } - $refs[ref].push(component.$vm || component); - }); - return $refs; - }, - }); -} -function findVmByVueId(instance, vuePid) { - // 标准 vue3 中 没有 $children,定制了内核 - const $children = instance.$children; - // 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200) - for (let i = $children.length - 1; i >= 0; i--) { - const childVm = $children[i]; - if (childVm.$scope._$vueId === vuePid) { - return childVm; - } - } - // 反向递归查找 - let parentVm; - for (let i = $children.length - 1; i >= 0; i--) { - parentVm = findVmByVueId($children[i], vuePid); - if (parentVm) { - return parentVm; - } - } -} - const PROP_TYPES = [String, Number, Boolean, Object, Array, null]; function createObserver(name) { return function observer(newVal) { @@ -537,18 +664,6 @@ function applyOptions(componentOptions, vueOptions, initBehavior) { componentOptions.behaviors = initBehaviors(vueOptions, initBehavior); } -function getValue(obj, path) { - const parts = path.split('.'); - let key = parts[0]; - if (key.indexOf('__$n') === 0) { - //number index - key = parseInt(key.replace('__$n', '')); - } - if (parts.length === 1) { - return obj[key]; - } - return getValue(obj[key], parts.slice(1).join('.')); -} function getExtraValue(instance, dataPathsArray) { let context = instance; dataPathsArray.forEach((dataPathArray) => { @@ -570,7 +685,7 @@ function getExtraValue(instance, dataPathsArray) { vFor = dataPath.substr(3); } else { - vFor = getValue(context, dataPath); + vFor = getTarget(context, dataPath); } } if (Number.isInteger(vFor)) { @@ -582,12 +697,12 @@ function getExtraValue(instance, dataPathsArray) { else { if (isArray(vFor)) { context = vFor.find((vForItem) => { - return getValue(vForItem, propPath) === value; + return getTarget(vForItem, propPath) === value; }); } else if (isPlainObject(vFor)) { context = Object.keys(vFor).find((vForKey) => { - return getValue(vFor[vForKey], propPath) === value; + return getTarget(vFor[vForKey], propPath) === value; }); } else { @@ -595,7 +710,7 @@ function getExtraValue(instance, dataPathsArray) { } } if (valuePath) { - context = getValue(context, valuePath); + context = getTarget(context, valuePath); } } }); @@ -636,10 +751,10 @@ function processEventExtra(instance, extra, event) { } else if (dataPath.indexOf('$event.') === 0) { // $event.target.value - extraObj['$' + index] = getValue(event, dataPath.replace('$event.', '')); + extraObj['$' + index] = getTarget(event, dataPath.replace('$event.', '')); } else { - extraObj['$' + index] = getValue(instance, dataPath); + extraObj['$' + index] = getTarget(instance, dataPath); } } } @@ -776,7 +891,14 @@ function handleEvent(event) { } handler.once = true; } - ret.push(handler.apply(handlerCtx, processEventArgs(this.$vm, event, eventArray[1], eventArray[2], isCustom, methodName))); + let params = processEventArgs(this.$vm, event, eventArray[1], eventArray[2], isCustom, methodName); + params = Array.isArray(params) ? params : []; + // 参数尾部增加原始事件对象用于复杂表达式内获取额外数据 + if (/=\s*\S+\.eventParams\s*\|\|\s*\S+\[['"]event-params['"]\]/.test(handler.toString())) { + // eslint-disable-next-line no-sparse-arrays + params = params.concat([, , , , , , , , , , event]); + } + ret.push(handler.apply(handlerCtx, params)); } }); } diff --git a/packages/uni-quickapp-webview/dist/uni.api.esm.js b/packages/uni-quickapp-webview/dist/uni.api.esm.js index 96ce7ac452dfb7af7e9f99190cf7a1e5802f6d70..986602cc8d03cce8b44c7cc929fd7fd05ec5150b 100644 --- a/packages/uni-quickapp-webview/dist/uni.api.esm.js +++ b/packages/uni-quickapp-webview/dist/uni.api.esm.js @@ -462,6 +462,114 @@ const removeInterceptor = defineSyncApi(API_REMOVE_INTERCEPTOR, (method, interce } }, RemoveInterceptorProtocol); +const API_ON = '$on'; +const OnProtocol = [ + { + name: 'event', + type: String, + required: true, + }, + { + name: 'callback', + type: Function, + required: true, + }, +]; +const API_ONCE = '$once'; +const OnceProtocol = OnProtocol; +const API_OFF = '$off'; +const OffProtocol = [ + { + name: 'event', + type: [String, Array], + }, + { + name: 'callback', + type: Function, + }, +]; +const API_EMIT = '$emit'; +const EmitProtocol = [ + { + name: 'event', + type: String, + required: true, + }, +]; + +const E = function () { + // Keep this empty so it's easier to inherit from + // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3) +}; +E.prototype = { + on: function (name, callback, ctx) { + var e = this.e || (this.e = {}); + (e[name] || (e[name] = [])).push({ + fn: callback, + ctx: ctx, + }); + return this; + }, + once: function (name, callback, ctx) { + var self = this; + function listener() { + self.off(name, listener); + callback.apply(ctx, arguments); + } + listener._ = callback; + return this.on(name, listener, ctx); + }, + emit: function (name) { + var data = [].slice.call(arguments, 1); + var evtArr = ((this.e || (this.e = {}))[name] || []).slice(); + var i = 0; + var len = evtArr.length; + for (i; i < len; i++) { + evtArr[i].fn.apply(evtArr[i].ctx, data); + } + return this; + }, + off: function (name, callback) { + var e = this.e || (this.e = {}); + var evts = e[name]; + var liveEvents = []; + if (evts && callback) { + for (var i = 0, len = evts.length; i < len; i++) { + if (evts[i].fn !== callback && evts[i].fn._ !== callback) + liveEvents.push(evts[i]); + } + } + // Remove event from queue to prevent memory leak + // Suggested by https://github.com/lazd + // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910 + liveEvents.length ? (e[name] = liveEvents) : delete e[name]; + return this; + }, +}; +var Emitter = E; + +const emitter = new Emitter(); +const $on = defineSyncApi(API_ON, (name, callback) => { + emitter.on(name, callback); + return () => emitter.off(name, callback); +}, OnProtocol); +const $once = defineSyncApi(API_ONCE, (name, callback) => { + emitter.once(name, callback); + return () => emitter.off(name, callback); +}, OnceProtocol); +const $off = defineSyncApi(API_OFF, (name, callback) => { + if (!name) { + emitter.e = {}; + return; + } + if (!Array.isArray(name)) + name = [name]; + name.forEach((n) => emitter.off(n, callback)); +}, OffProtocol); +const $emit = defineSyncApi(API_EMIT, (name, ...args) => { + emitter.emit(name, ...args); +}, EmitProtocol); + const SYNC_API_RE = /^\$|sendNativeEvent|restoreGlobal|getCurrentSubNVue|getMenuButtonBoundingClientRect|^report|interceptors|Interceptor$|getSubNVueById|requireNativePlugin|upx2px|hideKeyboard|canIUse|^create|Sync$|Manager$|base64ToArrayBuffer|arrayBufferToBase64/; const CONTEXT_API_RE = /^create|Manager$/; // Context例外情况 @@ -606,7 +714,15 @@ function initWrapper(protocols) { }; } -const baseApis = { upx2px, addInterceptor, removeInterceptor }; +const baseApis = { + $on, + $off, + $once, + $emit, + upx2px, + addInterceptor, + removeInterceptor, +}; function initUni(api, protocols) { const wrapper = initWrapper(protocols); const UniProxyHandlers = { diff --git a/packages/uni-quickapp-webview/dist/uni.mp.esm.js b/packages/uni-quickapp-webview/dist/uni.mp.esm.js index d9e14ddfd3ac916293c8c59f8f5c206d89b798b4..0677cd47c8a0a3c659cbb48c656a54453084c7c9 100644 --- a/packages/uni-quickapp-webview/dist/uni.mp.esm.js +++ b/packages/uni-quickapp-webview/dist/uni.mp.esm.js @@ -1,4 +1,4 @@ -import { isPlainObject, isArray, hasOwn, toNumber, isObject, isFunction, extend, NOOP, camelize } from '@vue/shared'; +import { isPlainObject, hasOwn, isArray, extend, hyphenate, isObject, toNumber, isFunction, NOOP, camelize } from '@vue/shared'; const encode = encodeURIComponent; function stringifyQuery(obj, encodeStr = encode) { @@ -19,6 +19,14 @@ function stringifyQuery(obj, encodeStr = encode) { : null; return res ? `?${res}` : ''; } + +function cache(fn) { + const cache = Object.create(null); + return (str) => { + const hit = cache[str]; + return hit || (cache[str] = fn(str)); + }; +} const invokeArrayFns = (fns, arg) => { let ret; for (let i = 0; i < fns.length; i++) { @@ -120,6 +128,183 @@ function getEventChannel(id) { return eventChannelStack.shift(); } +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) => { + const ref = component.dataset.ref; + $refs[ref] = component.$vm || component; + }); +} +function initRefs(instance, mpInstance) { + Object.defineProperty(instance, 'refs', { + get() { + const $refs = {}; + selectAllComponents(mpInstance, '.vue-ref', $refs); + const forComponents = mpInstance.selectAllComponents('.vue-ref-in-for'); + forComponents.forEach((component) => { + const ref = component.dataset.ref; + if (!$refs[ref]) { + $refs[ref] = []; + } + $refs[ref].push(component.$vm || component); + }); + return $refs; + }, + }); +} +function getTarget(obj, path) { + const parts = path.split('.'); + let key = parts[0]; + if (key.indexOf('__$n') === 0) { + //number index + key = parseInt(key.replace('__$n', '')); + } + if (!obj) { + obj = {}; + } + if (parts.length === 1) { + return obj[key]; + } + return getTarget(obj[key], parts.slice(1).join('.')); +} + +function getValue(dataPath, target) { + return getTarget(target || this, dataPath); +} +function getClass(dynamicClass, staticClass) { + return renderClass(staticClass, dynamicClass); +} +function getStyle(dynamicStyle, staticStyle) { + if (!dynamicStyle && !staticStyle) { + return ''; + } + var dynamicStyleObj = normalizeStyleBinding(dynamicStyle); + var styleObj = staticStyle + ? extend(staticStyle, dynamicStyleObj) + : dynamicStyleObj; + return Object.keys(styleObj) + .map(function (name) { + return hyphenate(name) + ':' + styleObj[name]; + }) + .join(';'); +} +function toObject(arr) { + var res = {}; + for (var i = 0; i < arr.length; i++) { + if (arr[i]) { + extend(res, arr[i]); + } + } + return res; +} +function normalizeStyleBinding(bindingStyle) { + if (Array.isArray(bindingStyle)) { + return toObject(bindingStyle); + } + if (typeof bindingStyle === 'string') { + return parseStyleText(bindingStyle); + } + return bindingStyle; +} +var parseStyleText = cache(function parseStyleText(cssText) { + var res = {}; + var listDelimiter = /;(?![^(]*\))/g; + var propertyDelimiter = /:(.+)/; + cssText.split(listDelimiter).forEach(function (item) { + if (item) { + var tmp = item.split(propertyDelimiter); + tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim()); + } + }); + return res; +}); +function isDef(v) { + return v !== undefined && v !== null; +} +function renderClass(staticClass, dynamicClass) { + if (isDef(staticClass) || isDef(dynamicClass)) { + return concat(staticClass, stringifyClass(dynamicClass)); + } + /* istanbul ignore next */ + return ''; +} +function concat(a, b) { + return a ? (b ? a + ' ' + b : a) : b || ''; +} +function stringifyClass(value) { + if (Array.isArray(value)) { + return stringifyArray(value); + } + if (isObject(value)) { + return stringifyObject(value); + } + if (typeof value === 'string') { + return value; + } + /* istanbul ignore next */ + return ''; +} +function stringifyArray(value) { + var res = ''; + var stringified; + for (var i = 0, l = value.length; i < l; i++) { + if (isDef((stringified = stringifyClass(value[i]))) && stringified !== '') { + if (res) { + res += ' '; + } + res += stringified; + } + } + return res; +} +function stringifyObject(value) { + var res = ''; + for (var key in value) { + if (value[key]) { + if (res) { + res += ' '; + } + res += key; + } + } + return res; +} + function setModel(target, key, value, modifiers) { if (isArray(modifiers)) { if (modifiers.indexOf('trim') !== -1) { @@ -229,7 +414,9 @@ function initComponentInstance(instance, options) { ctx.__set_sync = setSync; ctx.__get_orig = getOrig; // TODO - // ctx.__get_style = getStyle + ctx.__get_value = getValue; + ctx.__get_class = getClass; + ctx.__get_style = getStyle; ctx.__map = map; } function initMocks(instance, mpInstance, mocks) { @@ -356,66 +543,6 @@ function initCreateApp(parseAppOptions) { }; } -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) => { - const ref = component.dataset.ref; - $refs[ref] = component.$vm || component; - }); -} -function initRefs(instance, mpInstance) { - Object.defineProperty(instance, 'refs', { - get() { - const $refs = {}; - selectAllComponents(mpInstance, '.vue-ref', $refs); - const forComponents = mpInstance.selectAllComponents('.vue-ref-in-for'); - forComponents.forEach((component) => { - const ref = component.dataset.ref; - if (!$refs[ref]) { - $refs[ref] = []; - } - $refs[ref].push(component.$vm || component); - }); - return $refs; - }, - }); -} - const PROP_TYPES = [String, Number, Boolean, Object, Array, null]; function createObserver(name) { return function observer(newVal) { @@ -572,18 +699,6 @@ function applyOptions(componentOptions, vueOptions, initBehavior) { componentOptions.behaviors = initBehaviors(vueOptions, initBehavior); } -function getValue(obj, path) { - const parts = path.split('.'); - let key = parts[0]; - if (key.indexOf('__$n') === 0) { - //number index - key = parseInt(key.replace('__$n', '')); - } - if (parts.length === 1) { - return obj[key]; - } - return getValue(obj[key], parts.slice(1).join('.')); -} function getExtraValue(instance, dataPathsArray) { let context = instance; dataPathsArray.forEach((dataPathArray) => { @@ -605,7 +720,7 @@ function getExtraValue(instance, dataPathsArray) { vFor = dataPath.substr(3); } else { - vFor = getValue(context, dataPath); + vFor = getTarget(context, dataPath); } } if (Number.isInteger(vFor)) { @@ -617,12 +732,12 @@ function getExtraValue(instance, dataPathsArray) { else { if (isArray(vFor)) { context = vFor.find((vForItem) => { - return getValue(vForItem, propPath) === value; + return getTarget(vForItem, propPath) === value; }); } else if (isPlainObject(vFor)) { context = Object.keys(vFor).find((vForKey) => { - return getValue(vFor[vForKey], propPath) === value; + return getTarget(vFor[vForKey], propPath) === value; }); } else { @@ -630,7 +745,7 @@ function getExtraValue(instance, dataPathsArray) { } } if (valuePath) { - context = getValue(context, valuePath); + context = getTarget(context, valuePath); } } }); @@ -671,10 +786,10 @@ function processEventExtra(instance, extra, event) { } else if (dataPath.indexOf('$event.') === 0) { // $event.target.value - extraObj['$' + index] = getValue(event, dataPath.replace('$event.', '')); + extraObj['$' + index] = getTarget(event, dataPath.replace('$event.', '')); } else { - extraObj['$' + index] = getValue(instance, dataPath); + extraObj['$' + index] = getTarget(instance, dataPath); } } } @@ -811,7 +926,14 @@ function handleEvent(event) { } handler.once = true; } - ret.push(handler.apply(handlerCtx, processEventArgs(this.$vm, event, eventArray[1], eventArray[2], isCustom, methodName))); + let params = processEventArgs(this.$vm, event, eventArray[1], eventArray[2], isCustom, methodName); + params = Array.isArray(params) ? params : []; + // 参数尾部增加原始事件对象用于复杂表达式内获取额外数据 + if (/=\s*\S+\.eventParams\s*\|\|\s*\S+\[['"]event-params['"]\]/.test(handler.toString())) { + // eslint-disable-next-line no-sparse-arrays + params = params.concat([, , , , , , , , , , event]); + } + ret.push(handler.apply(handlerCtx, params)); } }); }