diff --git a/packages/uni-app-plus/dist/uni-app-service.es.js b/packages/uni-app-plus/dist/uni-app-service.es.js index 7c458b05b79b31025bc25ff72160f0edce0c0ea9..678d247537b225d4060cbdc44898ca983001e6b0 100644 --- a/packages/uni-app-plus/dist/uni-app-service.es.js +++ b/packages/uni-app-plus/dist/uni-app-service.es.js @@ -16025,7 +16025,7 @@ var serviceContext = (function (vue) { errMsg: 'getLocation:ok', }); } - const getLocation = defineAsyncApi(API_GET_LOCATION, ({ type = 'wgs84', geocode = false, altitude = false, highAccuracyExpireTime, }, { resolve, reject }) => { + const getLocation = defineAsyncApi(API_GET_LOCATION, ({ type = 'wgs84', geocode = false, altitude = false, highAccuracyExpireTime, isHighAccuracy = false, }, { resolve, reject }) => { plus.geolocation.getCurrentPosition((position) => { getLocationSuccess(type, position, resolve); }, (e) => { @@ -16037,7 +16037,7 @@ var serviceContext = (function (vue) { reject('getLocation:fail ' + e.message); }, { geocode: geocode, - enableHighAccuracy: altitude, + enableHighAccuracy: isHighAccuracy || altitude, timeout: highAccuracyExpireTime, }); }, GetLocationProtocol, GetLocationOptions); diff --git a/packages/uni-h5/dist/uni-h5.es.js b/packages/uni-h5/dist/uni-h5.es.js index 9d5f27ed16d7bdfff7f0c4011dd6209fdeab1291..de0961401513f709ba272fba566be9d227f856c5 100644 --- a/packages/uni-h5/dist/uni-h5.es.js +++ b/packages/uni-h5/dist/uni-h5.es.js @@ -17655,12 +17655,12 @@ function getJSONP(url, options, success, error) { js.src = url + (url.indexOf("?") >= 0 ? "&" : "?") + callbackKey + "=" + callbackName; document.body.appendChild(js); } -const getLocation = /* @__PURE__ */ defineAsyncApi(API_GET_LOCATION, ({ type, altitude, highAccuracyExpireTime }, { resolve, reject }) => { +const getLocation = /* @__PURE__ */ defineAsyncApi(API_GET_LOCATION, ({ type, altitude, highAccuracyExpireTime, isHighAccuracy }, { resolve, reject }) => { const mapInfo = getMapInfo(); new Promise((resolve2, reject2) => { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition((res) => resolve2(res.coords), reject2, { - enableHighAccuracy: altitude, + enableHighAccuracy: isHighAccuracy || altitude, timeout: highAccuracyExpireTime || 1e3 * 100 }); } else { diff --git a/packages/uni-mp-alipay/__tests__/ref.spec.ts b/packages/uni-mp-alipay/__tests__/ref.spec.ts index e4f42134796977a7b2c97f53b430b2924f6b4cf1..19c0561828fad2790877df1f69c2ef9ec6c95d36 100644 --- a/packages/uni-mp-alipay/__tests__/ref.spec.ts +++ b/packages/uni-mp-alipay/__tests__/ref.spec.ts @@ -54,14 +54,14 @@ export function render(_ctx, _cache) { ``, ``, `(_ctx, _cache) => { - return { a: (_value, _refs) => { _refs['custom'] = _value; } } + return { a: () => ({ r: custom }) } }` ) assert( ``, ``, `(_ctx, _cache) => { - return { a: _f(_ctx.items, (item, k0, i0) => { return { a: '2a9ec0b0-0' + '-' + i0 }; }), b: (_value, _refs) => { _refs['custom'] = _value; } } + return { a: _f(_ctx.items, (item, k0, i0) => { return { a: '2a9ec0b0-0' + '-' + i0 }; }), b: () => ({ r: custom, f: 1 }) } }` ) }) @@ -70,7 +70,7 @@ export function render(_ctx, _cache) { ``, ``, `(_ctx, _cache) => { - return { a: (_value, _refs) => { _refs['custom'] = _value; custom.value = _value; } } + return { a: () => ({ r: custom, k: 'custom' }) } }`, { bindingMetadata: { @@ -79,6 +79,34 @@ export function render(_ctx, _cache) { } ) }) + test('static ref with inline and setup-maybe-ref', () => { + assert( + ``, + ``, + `(_ctx, _cache) => { + return { a: () => ({ r: custom, k: 'custom' }) } +}`, + { + bindingMetadata: { + custom: BindingTypes.SETUP_MAYBE_REF, + }, + } + ) + }) + test('static ref with inline and setup-let', () => { + assert( + ``, + ``, + `(_ctx, _cache) => { + return { a: () => ({ r: custom, k: 'custom' }) } +}`, + { + bindingMetadata: { + custom: BindingTypes.SETUP_LET, + }, + } + ) + }) test('dynamic ref', () => { assert( ``, diff --git a/packages/uni-mp-alipay/dist/uni.mp.esm.js b/packages/uni-mp-alipay/dist/uni.mp.esm.js index 45f5062dd538c25f636de771f3eaf892242a0f16..de57b4fdbe65d94516d1eea38efc42fbd078a54e 100644 --- a/packages/uni-mp-alipay/dist/uni.mp.esm.js +++ b/packages/uni-mp-alipay/dist/uni.mp.esm.js @@ -1,5 +1,5 @@ -import { isPlainObject, hasOwn, isArray, capitalize, isFunction, extend, EMPTY_OBJ, isString, camelize } from '@vue/shared'; -import { injectHook, ref, toRaw, findComponentPropsData, updateProps, invalidateJob, isRef, pruneComponentPropsCache } from 'vue'; +import { isPlainObject, hasOwn, isArray, capitalize, isFunction, extend, isString, camelize } from '@vue/shared'; +import { injectHook, ref, toRaw, findComponentPropsData, updateProps, invalidateJob, EMPTY_OBJ, isRef, setTemplateRef, pruneComponentPropsCache } from 'vue'; // quickapp-webview 不能使用 default 作为插槽名称 const SLOT_DEFAULT_NAME = 'd'; @@ -162,6 +162,7 @@ function initBaseInstance(instance, options) { // mp ctx.mpType = options.mpType; // @deprecated ctx.$mpType = options.mpType; + ctx.$mpPlatform = "mp-alipay"; ctx.$scope = options.mpInstance; // TODO @deprecated ctx.$mp = {}; @@ -721,16 +722,17 @@ function handleRef(ref) { } const instance = this.$vm.$; const refs = instance.refs === EMPTY_OBJ ? (instance.refs = {}) : instance.refs; + const { setupState } = instance; const refValue = ref.$vm || ref; if (refName) { if (isString(refName)) { refs[refName] = refValue; - if (hasOwn(instance.setupState, refName)) { - instance.setupState[refName] = refValue; + if (hasOwn(setupState, refName)) { + setupState[refName] = refValue; } } else { - setRef(refName, refValue, refs); + setRef(refName, refValue, refs, setupState); } } else if (refInForName) { @@ -738,16 +740,22 @@ function handleRef(ref) { (refs[refInForName] || (refs[refInForName] = [])).push(refValue); } else { - setRef(refInForName, refValue, refs); + setRef(refInForName, refValue, refs, setupState); } } } -function setRef(ref, refValue, refs) { +function isTemplateRef(opts) { + return !!(opts && opts.r); +} +function setRef(ref, refValue, refs, setupState) { if (isRef(ref)) { ref.value = refValue; } else if (isFunction(ref)) { - ref(refValue, refs); + const templateRef = ref(refValue, refs); + if (isTemplateRef(templateRef)) { + setTemplateRef(templateRef, refValue, setupState); + } } } function triggerEvent(type, detail) { diff --git a/packages/uni-mp-alipay/src/runtime/util.ts b/packages/uni-mp-alipay/src/runtime/util.ts index 9c2ef99c7cdff05a14e76e0b5bfb3963d44f5655..f43ca140f4ee0355c95e7cf6efa76061dc076954 100644 --- a/packages/uni-mp-alipay/src/runtime/util.ts +++ b/packages/uni-mp-alipay/src/runtime/util.ts @@ -1,4 +1,11 @@ -import { hasOwn, isFunction, camelize, EMPTY_OBJ, isString } from '@vue/shared' +import { + hasOwn, + isFunction, + camelize, + isArray, + isString, + remove, +} from '@vue/shared' import { ComponentPublicInstance, @@ -7,8 +14,9 @@ import { isRef, Ref, } from 'vue' -// @ts-ignore -import { findComponentPropsData } from 'vue' + +// @ts-ignore EMPTY_OBJ 不能从 @vue/shared 中引入,从 vue 中导入,保持一致 +import { findComponentPropsData, EMPTY_OBJ, setTemplateRef } from 'vue' import { initMocks, @@ -20,7 +28,6 @@ import { import { handleLink as handleBaseLink } from '@dcloudio/uni-mp-weixin' -import deepEqual from './deepEqual' import { ON_READY } from '@dcloudio/uni-shared' type MPPageInstance = tinyapp.IPageInstance> @@ -142,34 +149,54 @@ export function handleRef(this: MPComponentInstance, ref: MPComponentInstance) { const refs = instance.refs === EMPTY_OBJ ? (instance.refs = {}) : instance.refs + const { setupState } = instance const refValue = ref.$vm || ref if (refName) { if (isString(refName)) { refs[refName] = refValue - if (hasOwn(instance.setupState, refName)) { - instance.setupState[refName] = refValue + if (hasOwn(setupState, refName)) { + setupState[refName] = refValue } } else { - setRef(refName, refValue, refs) + setRef(refName, refValue, refs, setupState) } } else if (refInForName) { if (isString(refInForName)) { ;(refs[refInForName] || (refs[refInForName] = [])).push(refValue) } else { - setRef(refInForName, refValue, refs) + setRef(refInForName, refValue, refs, setupState) } } } +type VNodeRef = + | string + | Ref + | ((ref: object | null, refs: Record) => void) + +type TemplateRef = { + r: VNodeRef + k?: string // setup ref key + f?: boolean // refInFor marker +} + +function isTemplateRef(opts: unknown): opts is TemplateRef { + return !!(opts && (opts as TemplateRef).r) +} + function setRef( ref: Ref | ((ref: object | null, refs: Record) => void), - refValue: Object, - refs: Record + refValue: ComponentPublicInstance, + refs: Record, + setupState: Data ) { if (isRef(ref)) { ref.value = refValue } else if (isFunction(ref)) { - ref(refValue, refs) + const templateRef = ref(refValue, refs) + if (isTemplateRef(templateRef)) { + setTemplateRef(templateRef, refValue, setupState) + } } } diff --git a/packages/uni-mp-baidu/dist/uni.mp.esm.js b/packages/uni-mp-baidu/dist/uni.mp.esm.js index 6789ea0c770b950d4a1cfcadd4b8548768e0451e..8f301d13bb6b67de8d75d1a388f7e197e36240cb 100644 --- a/packages/uni-mp-baidu/dist/uni.mp.esm.js +++ b/packages/uni-mp-baidu/dist/uni.mp.esm.js @@ -228,6 +228,7 @@ function initBaseInstance(instance, options) { // mp ctx.mpType = options.mpType; // @deprecated ctx.$mpType = options.mpType; + ctx.$mpPlatform = "mp-baidu"; ctx.$scope = options.mpInstance; // TODO @deprecated ctx.$mp = {}; diff --git a/packages/uni-mp-compiler/__tests__/ref.spec.ts b/packages/uni-mp-compiler/__tests__/ref.spec.ts index 8765e1b1a36e43ff3a25fd4a592cce909799f84c..3b9733b39b365216f9fa8a76c263d314821179c5 100644 --- a/packages/uni-mp-compiler/__tests__/ref.spec.ts +++ b/packages/uni-mp-compiler/__tests__/ref.spec.ts @@ -50,7 +50,7 @@ const __BINDING_COMPONENTS__ = '{"custom":{"name":"_component_custom","type":"un if (!Array) {const _component_custom = _resolveComponent("custom");Math.max.call(null, _component_custom);} export function render(_ctx, _cache) { - return { a: _f(_ctx.items, (item, k0, i0) => { return { a: _sr('custom', '2a9ec0b0-0' + '-' + i0), b: '2a9ec0b0-0' + '-' + i0 }; }) } + return { a: _f(_ctx.items, (item, k0, i0) => { return { a: _sr('custom', '2a9ec0b0-0' + '-' + i0, { "f": 1 }), b: '2a9ec0b0-0' + '-' + i0 }; }) } }`, { inline: false, @@ -63,7 +63,7 @@ export function render(_ctx, _cache) { ``, ``, `(_ctx, _cache) => { - return { a: _sr((_value, _refs) => { _refs['custom'] = _value; }, '2a9ec0b0-0') } + return { a: _sr('custom', '2a9ec0b0-0') } }`, { nodeTransforms, @@ -73,7 +73,7 @@ export function render(_ctx, _cache) { ``, ``, `(_ctx, _cache) => { - return { a: _f(_ctx.items, (item, k0, i0) => { return { a: _sr((_value, _refs) => { _refs['custom'] = _value; }, '2a9ec0b0-0' + '-' + i0), b: '2a9ec0b0-0' + '-' + i0 }; }) } + return { a: _f(_ctx.items, (item, k0, i0) => { return { a: _sr('custom', '2a9ec0b0-0' + '-' + i0, { "f": 1 }), b: '2a9ec0b0-0' + '-' + i0 }; }) } }`, { nodeTransforms, @@ -85,7 +85,7 @@ export function render(_ctx, _cache) { ``, ``, `(_ctx, _cache) => { - return { a: _sr((_value, _refs) => { _refs['custom'] = _value; custom.value = _value; }, '2a9ec0b0-0') } + return { a: _sr(custom, '2a9ec0b0-0', { "k": "custom" }) } }`, { bindingMetadata: { @@ -100,7 +100,7 @@ export function render(_ctx, _cache) { ``, ``, `(_ctx, _cache) => { - return { a: _sr((_value, _refs) => { _refs['custom'] = _value; _isRef(custom) && (custom.value = _value); }, '2a9ec0b0-0') } + return { a: _sr(custom, '2a9ec0b0-0', { "k": "custom" }) } }`, { bindingMetadata: { @@ -115,7 +115,7 @@ export function render(_ctx, _cache) { ``, ``, `(_ctx, _cache) => { - return { a: _sr((_value, _refs) => { _refs['custom'] = _value; _isRef(custom) ? custom.value = _value : custom = _value; }, '2a9ec0b0-0') } + return { a: _sr(custom, '2a9ec0b0-0', { "k": "custom" }) } }`, { bindingMetadata: { @@ -149,7 +149,7 @@ const __BINDING_COMPONENTS__ = '{"custom":{"name":"_component_custom","type":"un if (!Array) {const _component_custom = _resolveComponent("custom");Math.max.call(null, _component_custom);} export function render(_ctx, _cache) { - return { a: _f(_ctx.items, (item, k0, i0) => { return { a: _sr(_ctx.custom, '2a9ec0b0-0' + '-' + i0), b: '2a9ec0b0-0' + '-' + i0 }; }), b: _ctx.custom } + return { a: _f(_ctx.items, (item, k0, i0) => { return { a: _sr(_ctx.custom, '2a9ec0b0-0' + '-' + i0, { "f": 1 }), b: '2a9ec0b0-0' + '-' + i0 }; }), b: _ctx.custom } }`, { inline: false, @@ -172,7 +172,7 @@ export function render(_ctx, _cache) { ``, ``, `(_ctx, _cache) => { - return { a: _f(_ctx.items, (item, k0, i0) => { return { a: _sr(_ctx.custom, '2a9ec0b0-0' + '-' + i0), b: '2a9ec0b0-0' + '-' + i0 }; }), b: _ctx.custom } + return { a: _f(_ctx.items, (item, k0, i0) => { return { a: _sr(_ctx.custom, '2a9ec0b0-0' + '-' + i0, { "f": 1 }), b: '2a9ec0b0-0' + '-' + i0 }; }), b: _ctx.custom } }`, { nodeTransforms, diff --git a/packages/uni-mp-compiler/src/transforms/transformRef.ts b/packages/uni-mp-compiler/src/transforms/transformRef.ts index 9ae8cfd66238fcbab557c4cb34d53dd3e83cd8c0..da2c37dd13c255dbcbd1c615356eab7daf2cfd4a 100644 --- a/packages/uni-mp-compiler/src/transforms/transformRef.ts +++ b/packages/uni-mp-compiler/src/transforms/transformRef.ts @@ -1,24 +1,18 @@ import { arrowFunctionExpression, - assignmentExpression, - blockStatement, - callExpression, - conditionalExpression, Expression, - expressionStatement, identifier, - logicalExpression, - memberExpression, - Statement, + objectExpression, + objectProperty, + ObjectProperty, + numericLiteral, stringLiteral, } from '@babel/types' import { AttributeNode, - BindingTypes, DirectiveNode, ElementNode, findProp, - IS_REF, } from '@vue/compiler-core' import { createBindDirectiveNode, @@ -45,7 +39,7 @@ export function rewriteRef(node: ElementNode, context: TransformContext) { } if (findProp(node, 'ref')) { // 支付宝小程序 - const code = parseRefCode(refProp, vueIdProp, context) + const code = parseAlipayRefCode(refProp, context) if (code && context.inline && !isDirectiveNode(refProp)) { refProp.value!.content = code const refPropIndex = node.props.findIndex((prop) => prop === refProp) @@ -60,29 +54,40 @@ export function rewriteRef(node: ElementNode, context: TransformContext) { } } -function parseRefCode( +function parseRef( prop: AttributeNode | DirectiveNode, - vueIdProp: AttributeNode | DirectiveNode, context: TransformContext ) { let expr: Expression | undefined + let refKey = '' const isDir = isDirectiveNode(prop) if (isDir) { if (prop.exp) { expr = parseExpr(prop.exp, context, prop.exp) } } else { - if (prop.value?.content) { - expr = context.inline - ? processInlineRef(context, prop.value.content) - : stringLiteral(prop.value.content) + const { value } = prop + if (value && value.content) { + if (context.inline && context.bindingMetadata[value.content]) { + expr = identifier(value.content) + refKey = value.content + } else { + expr = stringLiteral(value.content) + } } } + return { expr, refKey } +} +function parseRefCode( + prop: AttributeNode | DirectiveNode, + context: TransformContext +) { + const { expr, refKey } = parseRef(prop, context) if (!expr) { - return + return { code: '', refKey } } - return genBabelExpr(expr) + return { code: genBabelExpr(expr), refKey } } function rewriteRefProp( @@ -102,72 +107,62 @@ function rewriteRefProp( if (!id) { return } + const { code, refKey } = parseRefCode(prop, context) + const opts = Object.create(null) + if (refKey) { + opts.k = refKey + } + if (context.inVFor) { + opts.f = 1 + } parseExprWithRewrite( context.helperString(SET_REF) + '(' + - parseRefCode(prop, vueIdProp, context) + + code + ', ' + id + + (Object.keys(opts).length ? ', ' + JSON.stringify(opts) : '') + ')', prop.loc, context ) } -function processInlineRef(context: TransformContext, raw: string) { - const statements: Statement[] = [] - statements.push( - expressionStatement( - assignmentExpression( - '=', - memberExpression(identifier('_refs'), stringLiteral(raw), true), - identifier('_value') - ) - ) - ) - const { bindingMetadata, helperString } = context - const type = bindingMetadata[raw] - if (type === BindingTypes.SETUP_REF) { - statements.push( - expressionStatement( - assignmentExpression( - '=', - memberExpression(identifier(raw), identifier('value')), - identifier('_value') - ) - ) - ) - } else if (type === BindingTypes.SETUP_MAYBE_REF) { - statements.push( - expressionStatement( - logicalExpression( - '&&', - callExpression(identifier(helperString(IS_REF)), [identifier(raw)]), - assignmentExpression( - '=', - memberExpression(identifier(raw), identifier('value')), - identifier('_value') - ) - ) - ) - ) - } else if (type === BindingTypes.SETUP_LET) { - statements.push( - expressionStatement( - conditionalExpression( - callExpression(identifier(helperString(IS_REF)), [identifier(raw)]), - assignmentExpression( - '=', - memberExpression(identifier(raw), identifier('value')), - identifier('_value') - ), - assignmentExpression('=', identifier(raw), identifier('_value')) - ) - ) - ) +function parseAlipayRefCode( + prop: AttributeNode | DirectiveNode, + context: TransformContext +) { + let expr: Expression | undefined + const isDir = isDirectiveNode(prop) + if (isDir) { + if (prop.exp) { + expr = parseExpr(prop.exp, context, prop.exp) + } + } else { + if (prop.value?.content) { + expr = context.inline + ? processInlineRef(prop, context) + : stringLiteral(prop.value.content) + } + } + + if (!expr) { + return } - return arrowFunctionExpression( - [identifier('_value'), identifier('_refs')], - blockStatement(statements) + return genBabelExpr(expr) +} + +function processInlineRef(prop: AttributeNode, context: TransformContext) { + const properties: ObjectProperty[] = [] + const { refKey } = parseRef(prop, context) + properties.push( + objectProperty(identifier('r'), identifier(prop.value!.content)) ) + if (refKey) { + properties.push(objectProperty(identifier('k'), stringLiteral(refKey))) + } + if (context.inVFor) { + properties.push(objectProperty(identifier('f'), numericLiteral(1))) + } + return arrowFunctionExpression([], objectExpression(properties)) } diff --git a/packages/uni-mp-core/src/runtime/componentInstance.ts b/packages/uni-mp-core/src/runtime/componentInstance.ts index 1b48aee792ecc92369ebed9667598c4a79778b34..a740d03b93e81643bd2bb643588712b6a14fbcdd 100644 --- a/packages/uni-mp-core/src/runtime/componentInstance.ts +++ b/packages/uni-mp-core/src/runtime/componentInstance.ts @@ -61,6 +61,7 @@ export function initBaseInstance( // mp ctx.mpType = options.mpType // @deprecated ctx.$mpType = options.mpType + ctx.$mpPlatform = __PLATFORM__ ctx.$scope = options.mpInstance // TODO @deprecated diff --git a/packages/uni-mp-kuaishou/dist/uni.mp.esm.js b/packages/uni-mp-kuaishou/dist/uni.mp.esm.js index 02fcec9545469b19660ac4ff9bde65239436d878..36b361529c360b250ef1c98eec8630b959eabf72 100644 --- a/packages/uni-mp-kuaishou/dist/uni.mp.esm.js +++ b/packages/uni-mp-kuaishou/dist/uni.mp.esm.js @@ -223,6 +223,7 @@ function initBaseInstance(instance, options) { // mp ctx.mpType = options.mpType; // @deprecated ctx.$mpType = options.mpType; + ctx.$mpPlatform = "mp-kuaishou"; ctx.$scope = options.mpInstance; // TODO @deprecated ctx.$mp = {}; diff --git a/packages/uni-mp-lark/dist/uni.mp.esm.js b/packages/uni-mp-lark/dist/uni.mp.esm.js index e22db2ae01ae8889151110b7c9b89923dce80a30..6f0cd1d90445b7899ae6193ea21670ff2436046e 100644 --- a/packages/uni-mp-lark/dist/uni.mp.esm.js +++ b/packages/uni-mp-lark/dist/uni.mp.esm.js @@ -219,6 +219,7 @@ function initBaseInstance(instance, options) { // mp ctx.mpType = options.mpType; // @deprecated ctx.$mpType = options.mpType; + ctx.$mpPlatform = "mp-lark"; ctx.$scope = options.mpInstance; // TODO @deprecated ctx.$mp = {}; diff --git a/packages/uni-mp-qq/dist/uni.mp.esm.js b/packages/uni-mp-qq/dist/uni.mp.esm.js index 40170976a3b992a7948af95d11855c05fb3c5ed0..c5849b4def5e483e2dd3146ed966995687150038 100644 --- a/packages/uni-mp-qq/dist/uni.mp.esm.js +++ b/packages/uni-mp-qq/dist/uni.mp.esm.js @@ -219,6 +219,7 @@ function initBaseInstance(instance, options) { // mp ctx.mpType = options.mpType; // @deprecated ctx.$mpType = options.mpType; + ctx.$mpPlatform = "mp-qq"; ctx.$scope = options.mpInstance; // TODO @deprecated ctx.$mp = {}; diff --git a/packages/uni-mp-toutiao/dist/uni.mp.esm.js b/packages/uni-mp-toutiao/dist/uni.mp.esm.js index b0d4b9f1566453a78a4e680a7875b7e5904ad7f8..8a78f0dfb754ef6feff36cb397baff371601f426 100644 --- a/packages/uni-mp-toutiao/dist/uni.mp.esm.js +++ b/packages/uni-mp-toutiao/dist/uni.mp.esm.js @@ -219,6 +219,7 @@ function initBaseInstance(instance, options) { // mp ctx.mpType = options.mpType; // @deprecated ctx.$mpType = options.mpType; + ctx.$mpPlatform = "mp-toutiao"; ctx.$scope = options.mpInstance; // TODO @deprecated ctx.$mp = {}; diff --git a/packages/uni-mp-vue/dist/vue.runtime.esm.js b/packages/uni-mp-vue/dist/vue.runtime.esm.js index 7a8abc41a29ccc697bf5f7a5faab6e0494a40073..2cd384b5b3dc196a7a45b573c1d5e91bfc6aa613 100644 --- a/packages/uni-mp-vue/dist/vue.runtime.esm.js +++ b/packages/uni-mp-vue/dist/vue.runtime.esm.js @@ -1,5 +1,5 @@ import { extend, isSymbol, isObject, toRawType, def, hasChanged, isArray, isFunction, NOOP, remove, toHandlerKey, hasOwn, camelize, hyphenate, isReservedProp, capitalize, isString, normalizeClass, normalizeStyle, isOn, isPromise, EMPTY_OBJ, isSet, isMap, isPlainObject, toTypeString, isIntegerKey, makeMap, invokeArrayFns, NO, toNumber, EMPTY_ARR, stringifyStyle as stringifyStyle$1, toDisplayString } from '@vue/shared'; -export { camelize, normalizeClass, normalizeProps, normalizeStyle, toDisplayString, toHandlerKey } from '@vue/shared'; +export { EMPTY_OBJ, camelize, normalizeClass, normalizeProps, normalizeStyle, toDisplayString, toHandlerKey } from '@vue/shared'; import { isRootHook, getValueByDataPath, ON_ERROR, UniLifecycleHooks, dynamicSlotName } from '@dcloudio/uni-shared'; function warn(msg, ...args) { @@ -4704,6 +4704,86 @@ function onApplyOptions(options, instance, publicThis) { delete instance.ctx.$onApplyOptions; } +/** + * Function for handling a template ref + */ +function setRef$1(instance, isUnmount = false) { + const { setupState, $templateRefs, ctx: { $scope, $mpPlatform } } = instance; + if ($mpPlatform === 'mp-alipay') { + return; + } + if (!$templateRefs || !$scope) { + return; + } + if (isUnmount) { + return $templateRefs.forEach(templateRef => setTemplateRef(templateRef, null, setupState)); + } + const doSet = () => { + const mpComponents = $scope + .selectAllComponents('.r') + .concat($scope.selectAllComponents('.r-i-f')); + $templateRefs.forEach(templateRef => setTemplateRef(templateRef, findComponentPublicInstance(mpComponents, templateRef.i), setupState)); + }; + if ($scope._$setRef) { + $scope._$setRef(doSet); + } + else { + nextTick$1(instance, doSet); + } +} +function findComponentPublicInstance(mpComponents, id) { + const mpInstance = mpComponents.find(com => com && (com.properties || com.props).uI === id); + if (mpInstance) { + return mpInstance.$vm; + } + return null; +} +function setTemplateRef({ r, f }, refValue, setupState) { + if (isFunction(r)) { + r(refValue, {}); + } + else { + const _isString = isString(r); + const _isRef = isRef(r); + if (_isString || _isRef) { + if (f) { + if (!_isRef) { + return; + } + if (!isArray(r.value)) { + r.value = []; + } + const existing = r.value; + if (existing.indexOf(refValue) === -1) { + existing.push(refValue); + if (!refValue) { + return; + } + // 实例销毁时,移除 + onBeforeUnmount(() => remove(existing, refValue), refValue.$); + } + } + else if (_isString) { + if (hasOwn(setupState, r)) { + setupState[r] = refValue; + } + } + else if (isRef(r)) { + r.value = refValue; + } + else if ((process.env.NODE_ENV !== 'production')) { + warnRef(r); + } + } + else if ((process.env.NODE_ENV !== 'production')) { + warnRef(r); + } + } +} +function warnRef(ref) { + warn$1('Invalid template ref type:', ref, `(${typeof ref})`); +} + var MPType; (function (MPType) { MPType["APP"] = "app"; @@ -4751,6 +4831,7 @@ const getFunctionalFallthrough = (attrs) => { }; function renderComponentRoot(instance) { const { type: Component, vnode, proxy, withProxy, props, slots, attrs, emit, render, renderCache, data, setupState, ctx, uid, appContext: { app: { config: { globalProperties: { pruneComponentPropsCache } } } } } = instance; + instance.$templateRefs = []; instance.$ei = 0; // props pruneComponentPropsCache(uid); @@ -4780,6 +4861,7 @@ function renderComponentRoot(instance) { handleError(err, instance, 1 /* RENDER_FUNCTION */); result = false; } + setRef$1(instance); setCurrentRenderingInstance(prev); return result; } @@ -4837,6 +4919,9 @@ function setupRenderEffect(instance) { instance.$updateScopedSlots = () => nextTick(() => queueJob(updateScopedSlots)); const componentUpdateFn = () => { if (!instance.isMounted) { + onBeforeUnmount(() => { + setRef$1(instance, true); + }, instance); patch(instance, renderComponentRoot(instance)); } else { @@ -5391,40 +5476,9 @@ function dynamicSlot(names) { return names.map((name) => dynamicSlotName(name)); } -function setRef(ref, id) { - const { proxy, ctx: { $scope }, setupState, } = getCurrentInstance(); - const doSet = () => { - let mpInstance = $scope - .selectAllComponents('.r') - .find((com) => com && com.properties.uI === id); - if (!mpInstance) { - mpInstance = $scope - .selectAllComponents('.r-i-f') - .find((com) => com && com.properties.uI === id); - } - if (!mpInstance) { - return; - } - // TODO 目前 $refs 实时从selectAllComponents中获取,不在 setRef 中对 $refs 做处理 - const refValue = mpInstance.$vm; - if (isString(ref)) { - if (hasOwn(setupState, ref)) { - setupState[ref] = refValue; - } - } - else if (isRef(ref)) { - ref.value = refValue; - } - else if (isFunction(ref)) { - ref(refValue, {}); - } - }; - if ($scope._$setRef) { - $scope._$setRef(doSet); - } - else { - proxy.$nextTick(doSet); - } +function setRef(ref, id, opts = {}) { + const { $templateRefs } = getCurrentInstance(); + $templateRefs.push({ i: id, r: ref, k: opts.k, f: opts.f }); } function setupDevtoolsPlugin() { @@ -5443,7 +5497,7 @@ const h = (str) => hyphenate(str); const n = (value) => normalizeClass(value); const t = (val) => toDisplayString(val); const p = (props) => renderProps(props); -const sr = (ref, id) => setRef(ref, id); +const sr = (ref, id, opts) => setRef(ref, id, opts); function createApp(rootComponent, rootProps = null) { rootComponent && (rootComponent.mpType = 'app'); @@ -5451,4 +5505,4 @@ function createApp(rootComponent, rootProps = null) { } const createSSRApp = createApp; -export { EffectScope, Fragment, ReactiveEffect, Text, c, callWithAsyncErrorHandling, callWithErrorHandling, computed, createApp, createSSRApp, createVNode$1 as createVNode, createVueApp, customRef, d, defineAsyncComponent, defineComponent, defineEmits, defineExpose, defineProps, diff, e, effect, effectScope, f, findComponentPropsData, getCurrentInstance, getCurrentScope, guardReactiveProps, h, inject, injectHook, invalidateJob, isInSSRComponentSetup, isProxy, isReactive, isReadonly, isRef, logError, markRaw, mergeDefaults, mergeProps, n, nextTick, o, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onServerPrefetch, onUnmounted, onUpdated, p, patch, provide, proxyRefs, pruneComponentPropsCache, queuePostFlushCb, r, reactive, readonly, ref, resolveComponent, resolveDirective, resolveFilter, s, setCurrentRenderingInstance, setupDevtoolsPlugin, shallowReactive, shallowReadonly, shallowRef, sr, stop, t, toHandlers, toRaw, toRef, toRefs, triggerRef, unref, updateProps, useAttrs, useCssModule, useCssVars, useSSRContext, useSlots, version, w, warn$1 as warn, watch, watchEffect, watchPostEffect, watchSyncEffect, withAsyncContext, withCtx, withDefaults, withDirectives, withModifiers, withScopeId }; +export { EffectScope, Fragment, ReactiveEffect, Text, c, callWithAsyncErrorHandling, callWithErrorHandling, computed, createApp, createSSRApp, createVNode$1 as createVNode, createVueApp, customRef, d, defineAsyncComponent, defineComponent, defineEmits, defineExpose, defineProps, diff, e, effect, effectScope, f, findComponentPropsData, getCurrentInstance, getCurrentScope, guardReactiveProps, h, inject, injectHook, invalidateJob, isInSSRComponentSetup, isProxy, isReactive, isReadonly, isRef, logError, markRaw, mergeDefaults, mergeProps, n, nextTick, o, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onServerPrefetch, onUnmounted, onUpdated, p, patch, provide, proxyRefs, pruneComponentPropsCache, queuePostFlushCb, r, reactive, readonly, ref, resolveComponent, resolveDirective, resolveFilter, s, setCurrentRenderingInstance, setTemplateRef, setupDevtoolsPlugin, shallowReactive, shallowReadonly, shallowRef, sr, stop, t, toHandlers, toRaw, toRef, toRefs, triggerRef, unref, updateProps, useAttrs, useCssModule, useCssVars, useSSRContext, useSlots, version, w, warn$1 as warn, watch, watchEffect, watchPostEffect, watchSyncEffect, withAsyncContext, withCtx, withDefaults, withDirectives, withModifiers, withScopeId }; diff --git a/packages/uni-mp-vue/lib/vue.runtime.esm.js b/packages/uni-mp-vue/lib/vue.runtime.esm.js index cf1f2ce5c09b3eac4b7108e9225ce4fa65a532a0..bba7b4b7656c638d6365d23ea31ae2983f681a1f 100644 --- a/packages/uni-mp-vue/lib/vue.runtime.esm.js +++ b/packages/uni-mp-vue/lib/vue.runtime.esm.js @@ -1,5 +1,5 @@ import { extend, isArray, isMap, isIntegerKey, isSymbol, hasOwn, isObject, hasChanged, makeMap, capitalize, toRawType, def, isFunction, NOOP, isOn, hyphenate, EMPTY_OBJ, toHandlerKey, toNumber, camelize, remove, isPromise, isString, isReservedProp, EMPTY_ARR, NO, normalizeClass, normalizeStyle, isSet, isPlainObject, toTypeString, invokeArrayFns } from '@vue/shared'; -export { camelize, normalizeClass, normalizeProps, normalizeStyle, toDisplayString, toHandlerKey } from '@vue/shared'; +export { EMPTY_OBJ, camelize, normalizeClass, normalizeProps, normalizeStyle, toDisplayString, toHandlerKey } from '@vue/shared'; import { isRootHook, getValueByDataPath } from '@dcloudio/uni-shared'; function warn(msg, ...args) { @@ -4704,6 +4704,86 @@ function onApplyOptions(options, instance, publicThis) { delete instance.ctx.$onApplyOptions; } +/** + * Function for handling a template ref + */ +function setRef(instance, isUnmount = false) { + const { setupState, $templateRefs, ctx: { $scope, $mpPlatform } } = instance; + if ($mpPlatform === 'mp-alipay') { + return; + } + if (!$templateRefs || !$scope) { + return; + } + if (isUnmount) { + return $templateRefs.forEach(templateRef => setTemplateRef(templateRef, null, setupState)); + } + const doSet = () => { + const mpComponents = $scope + .selectAllComponents('.r') + .concat($scope.selectAllComponents('.r-i-f')); + $templateRefs.forEach(templateRef => setTemplateRef(templateRef, findComponentPublicInstance(mpComponents, templateRef.i), setupState)); + }; + if ($scope._$setRef) { + $scope._$setRef(doSet); + } + else { + nextTick$1(instance, doSet); + } +} +function findComponentPublicInstance(mpComponents, id) { + const mpInstance = mpComponents.find(com => com && (com.properties || com.props).uI === id); + if (mpInstance) { + return mpInstance.$vm; + } + return null; +} +function setTemplateRef({ r, f }, refValue, setupState) { + if (isFunction(r)) { + r(refValue, {}); + } + else { + const _isString = isString(r); + const _isRef = isRef(r); + if (_isString || _isRef) { + if (f) { + if (!_isRef) { + return; + } + if (!isArray(r.value)) { + r.value = []; + } + const existing = r.value; + if (existing.indexOf(refValue) === -1) { + existing.push(refValue); + if (!refValue) { + return; + } + // 实例销毁时,移除 + onBeforeUnmount(() => remove(existing, refValue), refValue.$); + } + } + else if (_isString) { + if (hasOwn(setupState, r)) { + setupState[r] = refValue; + } + } + else if (isRef(r)) { + r.value = refValue; + } + else if ((process.env.NODE_ENV !== 'production')) { + warnRef(r); + } + } + else if ((process.env.NODE_ENV !== 'production')) { + warnRef(r); + } + } +} +function warnRef(ref) { + warn$1('Invalid template ref type:', ref, `(${typeof ref})`); +} + var MPType; (function (MPType) { MPType["APP"] = "app"; @@ -4751,6 +4831,7 @@ const getFunctionalFallthrough = (attrs) => { }; function renderComponentRoot(instance) { const { type: Component, vnode, proxy, withProxy, props, slots, attrs, emit, render, renderCache, data, setupState, ctx, uid, appContext: { app: { config: { globalProperties: { pruneComponentPropsCache } } } } } = instance; + instance.$templateRefs = []; instance.$ei = 0; // props pruneComponentPropsCache(uid); @@ -4780,6 +4861,7 @@ function renderComponentRoot(instance) { handleError(err, instance, 1 /* RENDER_FUNCTION */); result = false; } + setRef(instance); setCurrentRenderingInstance(prev); return result; } @@ -4837,6 +4919,9 @@ function setupRenderEffect(instance) { instance.$updateScopedSlots = () => nextTick(() => queueJob(updateScopedSlots)); const componentUpdateFn = () => { if (!instance.isMounted) { + onBeforeUnmount(() => { + setRef(instance, true); + }, instance); patch(instance, renderComponentRoot(instance)); } else { @@ -4986,4 +5071,4 @@ function initCssVarsRender(instance, getter) { function withModifiers() { } function createVNode$1() { } -export { EffectScope, Fragment, ReactiveEffect, Text, callWithAsyncErrorHandling, callWithErrorHandling, computed, createVNode$1 as createVNode, createVueApp, customRef, defineAsyncComponent, defineComponent, defineEmits, defineExpose, defineProps, diff, effect, effectScope, getCurrentInstance, getCurrentScope, guardReactiveProps, inject, injectHook, invalidateJob, isInSSRComponentSetup, isProxy, isReactive, isReadonly, isRef, logError, markRaw, mergeDefaults, mergeProps, nextTick, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onServerPrefetch, onUnmounted, onUpdated, patch, provide, proxyRefs, queuePostFlushCb, reactive, readonly, ref, resolveComponent, resolveDirective, resolveFilter, setCurrentRenderingInstance, shallowReactive, shallowReadonly, shallowRef, stop, toHandlers, toRaw, toRef, toRefs, triggerRef, unref, updateProps, useAttrs, useCssModule, useCssVars, useSSRContext, useSlots, version, warn$1 as warn, watch, watchEffect, watchPostEffect, watchSyncEffect, withAsyncContext, withCtx, withDefaults, withDirectives, withModifiers, withScopeId }; +export { EffectScope, Fragment, ReactiveEffect, Text, callWithAsyncErrorHandling, callWithErrorHandling, computed, createVNode$1 as createVNode, createVueApp, customRef, defineAsyncComponent, defineComponent, defineEmits, defineExpose, defineProps, diff, effect, effectScope, getCurrentInstance, getCurrentScope, guardReactiveProps, inject, injectHook, invalidateJob, isInSSRComponentSetup, isProxy, isReactive, isReadonly, isRef, logError, markRaw, mergeDefaults, mergeProps, nextTick, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onServerPrefetch, onUnmounted, onUpdated, patch, provide, proxyRefs, queuePostFlushCb, reactive, readonly, ref, resolveComponent, resolveDirective, resolveFilter, setCurrentRenderingInstance, setTemplateRef, shallowReactive, shallowReadonly, shallowRef, stop, toHandlers, toRaw, toRef, toRefs, triggerRef, unref, updateProps, useAttrs, useCssModule, useCssVars, useSSRContext, useSlots, version, warn$1 as warn, watch, watchEffect, watchPostEffect, watchSyncEffect, withAsyncContext, withCtx, withDefaults, withDirectives, withModifiers, withScopeId }; diff --git a/packages/uni-mp-vue/src/helpers/index.ts b/packages/uni-mp-vue/src/helpers/index.ts index dd09acef6f1cbe0745c6d97c41b81734e2722e70..1c12d2d64fb6441eba57cf2daf08559e71f1ef16 100644 --- a/packages/uni-mp-vue/src/helpers/index.ts +++ b/packages/uni-mp-vue/src/helpers/index.ts @@ -37,4 +37,4 @@ export const h: typeof hyphenate = (str) => hyphenate(str) export const n: typeof normalizeClass = (value) => normalizeClass(value) export const t: typeof toDisplayString = (val) => toDisplayString(val) export const p: typeof renderProps = (props) => renderProps(props) -export const sr: typeof setRef = (ref, id) => setRef(ref, id) +export const sr: typeof setRef = (ref, id, opts) => setRef(ref, id, opts) diff --git a/packages/uni-mp-vue/src/helpers/ref.ts b/packages/uni-mp-vue/src/helpers/ref.ts index 6766d9c3903634e088a707a704906ccca4e63b76..7e526412bdf6af7c1785b1670ceecfa2a1f4235b 100644 --- a/packages/uni-mp-vue/src/helpers/ref.ts +++ b/packages/uni-mp-vue/src/helpers/ref.ts @@ -1,49 +1,30 @@ -import type { MPComponentInstance } from '@dcloudio/uni-mp-core' -import { ComponentInternalInstance, getCurrentInstance, isRef, Ref } from 'vue' -import { hasOwn, isFunction, isString } from '@vue/shared' +import { ComponentInternalInstance, getCurrentInstance, Ref } from 'vue' +// @ts-ignore +import { getExposeProxy } from 'vue' -export type VNodeRef = +type VNodeRef = | string | Ref | ((ref: object | null, refs: Record) => void) -export function setRef(ref: VNodeRef, id: string) { - const { - proxy, - ctx: { $scope }, - setupState, - } = getCurrentInstance()! as ComponentInternalInstance & { - ctx: { $scope: MPComponentInstance } - setupState: Record - } - const doSet = () => { - let mpInstance = $scope - .selectAllComponents('.r') - .find((com) => com && com.properties.uI === id) - if (!mpInstance) { - mpInstance = $scope - .selectAllComponents('.r-i-f') - .find((com) => com && com.properties.uI === id) - } - if (!mpInstance) { - return - } - // TODO 目前 $refs 实时从selectAllComponents中获取,不在 setRef 中对 $refs 做处理 - const refValue = mpInstance.$vm - if (isString(ref)) { - if (hasOwn(setupState, ref)) { - setupState[ref] = refValue - } - } else if (isRef(ref)) { - ref.value = refValue - } else if (isFunction(ref)) { - ref(refValue, {}) - } - } +export type TemplateRef = { + i: string // id + r: VNodeRef + k?: string // setup ref key + f?: boolean // refInFor marker +} - if ($scope._$setRef) { - $scope._$setRef(doSet) - } else { - proxy!.$nextTick(doSet) - } +export function setRef( + ref: VNodeRef, + id: string, + opts: { + k?: string + f?: boolean + } = {} +): void { + const { $templateRefs } = + getCurrentInstance()! as ComponentInternalInstance & { + $templateRefs: TemplateRef[] + } + $templateRefs.push({ i: id, r: ref, k: opts.k, f: opts.f }) } diff --git a/packages/uni-mp-weixin/dist/uni.mp.esm.js b/packages/uni-mp-weixin/dist/uni.mp.esm.js index f0379d981d21e32bd4cf8db018d23636e95c8cec..5d997ec3c297045c2e117336a6d54ecf10fe0cf5 100644 --- a/packages/uni-mp-weixin/dist/uni.mp.esm.js +++ b/packages/uni-mp-weixin/dist/uni.mp.esm.js @@ -91,6 +91,7 @@ function initBaseInstance(instance, options) { // mp ctx.mpType = options.mpType; // @deprecated ctx.$mpType = options.mpType; + ctx.$mpPlatform = "mp-weixin"; ctx.$scope = options.mpInstance; // TODO @deprecated ctx.$mp = {}; diff --git a/packages/uni-quickapp-webview/dist/uni.mp.esm.js b/packages/uni-quickapp-webview/dist/uni.mp.esm.js index cfba831f30e56f7646f7b86e7c517d3e7ffff4cd..4e80dac82e92e4a471814346f791963a047714f5 100644 --- a/packages/uni-quickapp-webview/dist/uni.mp.esm.js +++ b/packages/uni-quickapp-webview/dist/uni.mp.esm.js @@ -219,6 +219,7 @@ function initBaseInstance(instance, options) { // mp ctx.mpType = options.mpType; // @deprecated ctx.$mpType = options.mpType; + ctx.$mpPlatform = "quickapp-webview"; ctx.$scope = options.mpInstance; // TODO @deprecated ctx.$mp = {};