提交 531e2e39 编写于 作者: fxy060608's avatar fxy060608

feat(mp): support ref in v-for

上级 789d9718
......@@ -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);
......
......@@ -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 {
......
......@@ -54,14 +54,14 @@ export function render(_ctx, _cache) {
`<custom ref="custom"/>`,
`<custom ref="__r" u-r="{{a}}" u-i="2a9ec0b0-0" onVI="__l"/>`,
`(_ctx, _cache) => {
return { a: (_value, _refs) => { _refs['custom'] = _value; } }
return { a: () => ({ r: custom }) }
}`
)
assert(
`<custom v-for="item in items" ref="custom"/>`,
`<custom a:for="{{a}}" a:for-item="item" ref="__r" u-r-i-f="{{b}}" u-i="{{item.a}}" onVI="__l"/>`,
`(_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) {
`<custom ref="custom"/>`,
`<custom ref="__r" u-r="{{a}}" u-i="2a9ec0b0-0" onVI="__l"/>`,
`(_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(
`<custom ref="custom"/>`,
`<custom ref="__r" u-r="{{a}}" u-i="2a9ec0b0-0" onVI="__l"/>`,
`(_ctx, _cache) => {
return { a: () => ({ r: custom, k: 'custom' }) }
}`,
{
bindingMetadata: {
custom: BindingTypes.SETUP_MAYBE_REF,
},
}
)
})
test('static ref with inline and setup-let', () => {
assert(
`<custom ref="custom"/>`,
`<custom ref="__r" u-r="{{a}}" u-i="2a9ec0b0-0" onVI="__l"/>`,
`(_ctx, _cache) => {
return { a: () => ({ r: custom, k: 'custom' }) }
}`,
{
bindingMetadata: {
custom: BindingTypes.SETUP_LET,
},
}
)
})
test('dynamic ref', () => {
assert(
`<custom :ref="custom"/>`,
......
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) {
......
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<Record<string, any>>
......@@ -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<string, any>) => 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<string, any>) => void),
refValue: Object,
refs: Record<string, unknown>
refValue: ComponentPublicInstance,
refs: Record<string, unknown>,
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)
}
}
}
......
......@@ -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 = {};
......
......@@ -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) {
`<custom ref="custom"/>`,
`<custom class="r" u-r="custom" u-i="2a9ec0b0-0"/>`,
`(_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) {
`<custom v-for="item in items" ref="custom"/>`,
`<custom wx:for="{{a}}" wx:for-item="item" class="r-i-f" u-r="custom" u-i="{{item.b}}"/>`,
`(_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) {
`<custom ref="custom"/>`,
`<custom class="r" u-r="custom" u-i="2a9ec0b0-0"/>`,
`(_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) {
`<custom ref="custom"/>`,
`<custom class="r" u-r="custom" u-i="2a9ec0b0-0"/>`,
`(_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) {
`<custom ref="custom"/>`,
`<custom class="r" u-r="custom" u-i="2a9ec0b0-0"/>`,
`(_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) {
`<custom v-for="item in items" :ref="custom"/>`,
`<custom wx:for="{{a}}" wx:for-item="item" class="r-i-f" u-r="{{b}}" u-i="{{item.b}}"/>`,
`(_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,
......
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))
}
......@@ -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
......
......@@ -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 = {};
......
......@@ -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 = {};
......
......@@ -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 = {};
......
......@@ -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 = {};
......
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 };
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 };
......@@ -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)
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<string, any>) => void)
export function setRef(ref: VNodeRef, id: string) {
const {
proxy,
ctx: { $scope },
setupState,
} = getCurrentInstance()! as ComponentInternalInstance & {
ctx: { $scope: MPComponentInstance }
setupState: Record<string, unknown>
}
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 })
}
......@@ -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 = {};
......
......@@ -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 = {};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册