fix(compiler-sfc): defineProps return binding or rest binding should be considered reactive
This commit is contained in:
parent
03b03eee44
commit
410144149f
@ -97,6 +97,10 @@ export const enum BindingTypes {
|
|||||||
* template expressions.
|
* template expressions.
|
||||||
*/
|
*/
|
||||||
SETUP_CONST = 'setup-const',
|
SETUP_CONST = 'setup-const',
|
||||||
|
/**
|
||||||
|
* a const binding that does not need `unref()`, but may be mutated.
|
||||||
|
*/
|
||||||
|
SETUP_REACTIVE_CONST = 'setup-reactive-const',
|
||||||
/**
|
/**
|
||||||
* a const binding that may be a ref.
|
* a const binding that may be a ref.
|
||||||
*/
|
*/
|
||||||
|
@ -352,7 +352,9 @@ function resolveSetupReference(name: string, context: TransformContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const fromConst = checkType(BindingTypes.SETUP_CONST)
|
const fromConst =
|
||||||
|
checkType(BindingTypes.SETUP_CONST) ||
|
||||||
|
checkType(BindingTypes.SETUP_REACTIVE_CONST)
|
||||||
if (fromConst) {
|
if (fromConst) {
|
||||||
return context.inline
|
return context.inline
|
||||||
? // in inline mode, const setup bindings (e.g. imports) can be used as-is
|
? // in inline mode, const setup bindings (e.g. imports) can be used as-is
|
||||||
|
@ -122,7 +122,11 @@ export function processExpression(
|
|||||||
const isDestructureAssignment =
|
const isDestructureAssignment =
|
||||||
parent && isInDestructureAssignment(parent, parentStack)
|
parent && isInDestructureAssignment(parent, parentStack)
|
||||||
|
|
||||||
if (type === BindingTypes.SETUP_CONST || localVars[raw]) {
|
if (
|
||||||
|
type === BindingTypes.SETUP_CONST ||
|
||||||
|
type === BindingTypes.SETUP_REACTIVE_CONST ||
|
||||||
|
localVars[raw]
|
||||||
|
) {
|
||||||
return raw
|
return raw
|
||||||
} else if (type === BindingTypes.SETUP_REF) {
|
} else if (type === BindingTypes.SETUP_REF) {
|
||||||
return `${raw}.value`
|
return `${raw}.value`
|
||||||
|
@ -68,7 +68,7 @@ const bar = 1
|
|||||||
expect(bindings).toStrictEqual({
|
expect(bindings).toStrictEqual({
|
||||||
foo: BindingTypes.PROPS,
|
foo: BindingTypes.PROPS,
|
||||||
bar: BindingTypes.SETUP_CONST,
|
bar: BindingTypes.SETUP_CONST,
|
||||||
props: BindingTypes.SETUP_CONST
|
props: BindingTypes.SETUP_REACTIVE_CONST
|
||||||
})
|
})
|
||||||
|
|
||||||
// should remove defineOptions import and call
|
// should remove defineOptions import and call
|
||||||
|
@ -141,7 +141,7 @@ describe('sfc props transform', () => {
|
|||||||
foo: BindingTypes.PROPS,
|
foo: BindingTypes.PROPS,
|
||||||
bar: BindingTypes.PROPS,
|
bar: BindingTypes.PROPS,
|
||||||
baz: BindingTypes.PROPS,
|
baz: BindingTypes.PROPS,
|
||||||
rest: BindingTypes.SETUP_CONST
|
rest: BindingTypes.SETUP_REACTIVE_CONST
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1207,7 +1207,8 @@ export function compileScript(
|
|||||||
// props aliases
|
// props aliases
|
||||||
if (propsDestructureDecl) {
|
if (propsDestructureDecl) {
|
||||||
if (propsDestructureRestId) {
|
if (propsDestructureRestId) {
|
||||||
bindingMetadata[propsDestructureRestId] = BindingTypes.SETUP_CONST
|
bindingMetadata[propsDestructureRestId] =
|
||||||
|
BindingTypes.SETUP_REACTIVE_CONST
|
||||||
}
|
}
|
||||||
for (const key in propsDestructuredBindings) {
|
for (const key in propsDestructuredBindings) {
|
||||||
const { local } = propsDestructuredBindings[key]
|
const { local } = propsDestructuredBindings[key]
|
||||||
@ -1525,14 +1526,18 @@ function walkDeclaration(
|
|||||||
const userReactiveBinding = userImportAlias['reactive'] || 'reactive'
|
const userReactiveBinding = userImportAlias['reactive'] || 'reactive'
|
||||||
if (isCallOf(init, userReactiveBinding)) {
|
if (isCallOf(init, userReactiveBinding)) {
|
||||||
// treat reactive() calls as let since it's meant to be mutable
|
// treat reactive() calls as let since it's meant to be mutable
|
||||||
bindingType = BindingTypes.SETUP_LET
|
bindingType = isConst
|
||||||
|
? BindingTypes.SETUP_REACTIVE_CONST
|
||||||
|
: BindingTypes.SETUP_LET
|
||||||
} else if (
|
} else if (
|
||||||
// if a declaration is a const literal, we can mark it so that
|
// if a declaration is a const literal, we can mark it so that
|
||||||
// the generated render fn code doesn't need to unref() it
|
// the generated render fn code doesn't need to unref() it
|
||||||
isDefineCall ||
|
isDefineCall ||
|
||||||
(isConst && canNeverBeRef(init!, userReactiveBinding))
|
(isConst && canNeverBeRef(init!, userReactiveBinding))
|
||||||
) {
|
) {
|
||||||
bindingType = BindingTypes.SETUP_CONST
|
bindingType = isCallOf(init, DEFINE_PROPS)
|
||||||
|
? BindingTypes.SETUP_REACTIVE_CONST
|
||||||
|
: BindingTypes.SETUP_CONST
|
||||||
} else if (isConst) {
|
} else if (isConst) {
|
||||||
if (isCallOf(init, userImportAlias['ref'] || 'ref')) {
|
if (isCallOf(init, userImportAlias['ref'] || 'ref')) {
|
||||||
bindingType = BindingTypes.SETUP_REF
|
bindingType = BindingTypes.SETUP_REF
|
||||||
|
Loading…
Reference in New Issue
Block a user