Skip to content

Commit f29d061

Browse files
authored
fix(compiler): fix template ref codegen for setup-maybe-ref binding types (#4549)
fix #4546
1 parent 14fcced commit f29d061

File tree

2 files changed

+95
-6
lines changed

2 files changed

+95
-6
lines changed

packages/compiler-core/__tests__/transforms/transformElement.spec.ts

+75
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,81 @@ describe('compiler: element transform', () => {
10041004
})
10051005
})
10061006

1007+
test('the binding not exists (inline maybe ref input)', () => {
1008+
const { node } = parseWithElementTransform(`<input ref="input"/>`, {
1009+
inline: true,
1010+
bindingMetadata: {
1011+
input: BindingTypes.SETUP_MAYBE_REF
1012+
}
1013+
})
1014+
expect(node.props).toMatchObject({
1015+
type: NodeTypes.JS_OBJECT_EXPRESSION,
1016+
properties: [
1017+
{
1018+
type: NodeTypes.JS_PROPERTY,
1019+
key: {
1020+
type: NodeTypes.SIMPLE_EXPRESSION,
1021+
content: 'ref',
1022+
isStatic: true
1023+
},
1024+
value: {
1025+
type: NodeTypes.JS_FUNCTION_EXPRESSION,
1026+
params: ['_value', '_refs'],
1027+
body: {
1028+
type: NodeTypes.JS_BLOCK_STATEMENT,
1029+
body: [
1030+
{
1031+
content: `_refs['input'] = _value`
1032+
},
1033+
{
1034+
content: '_isRef(input) && (input.value = _value)'
1035+
}
1036+
]
1037+
}
1038+
}
1039+
}
1040+
]
1041+
})
1042+
})
1043+
1044+
test('the binding not exists (inline let ref input)', () => {
1045+
const { node } = parseWithElementTransform(`<input ref="input"/>`, {
1046+
inline: true,
1047+
bindingMetadata: {
1048+
input: BindingTypes.SETUP_LET
1049+
}
1050+
})
1051+
expect(node.props).toMatchObject({
1052+
type: NodeTypes.JS_OBJECT_EXPRESSION,
1053+
properties: [
1054+
{
1055+
type: NodeTypes.JS_PROPERTY,
1056+
key: {
1057+
type: NodeTypes.SIMPLE_EXPRESSION,
1058+
content: 'ref',
1059+
isStatic: true
1060+
},
1061+
value: {
1062+
type: NodeTypes.JS_FUNCTION_EXPRESSION,
1063+
params: ['_value', '_refs'],
1064+
body: {
1065+
type: NodeTypes.JS_BLOCK_STATEMENT,
1066+
body: [
1067+
{
1068+
content: `_refs['input'] = _value`
1069+
},
1070+
{
1071+
content:
1072+
'_isRef(input) ? input.value = _value : input = _value'
1073+
}
1074+
]
1075+
}
1076+
}
1077+
}
1078+
]
1079+
})
1080+
})
1081+
10071082
test('HYDRATE_EVENTS', () => {
10081083
// ignore click events (has dedicated fast path)
10091084
const { node } = parseWithElementTransform(`<div @click="foo" />`, {

packages/compiler-core/src/transforms/transformElement.ts

+20-6
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ import {
4848
KEEP_ALIVE,
4949
SUSPENSE,
5050
UNREF,
51-
GUARD_REACTIVE_PROPS
51+
GUARD_REACTIVE_PROPS,
52+
IS_REF
5253
} from '../runtimeHelpers'
5354
import {
5455
getInnerRange,
@@ -61,7 +62,7 @@ import {
6162
} from '../utils'
6263
import { buildSlots } from './vSlot'
6364
import { getConstantType } from './hoistStatic'
64-
import { BindingMetadata, BindingTypes } from '../options'
65+
import { BindingTypes } from '../options'
6566
import {
6667
checkCompatEnabled,
6768
CompilerDeprecationTypes,
@@ -475,7 +476,7 @@ export function buildProps(
475476
if (!__BROWSER__ && context.inline && value?.content) {
476477
valueNode = createFunctionExpression(['_value', '_refs'])
477478
valueNode.body = createBlockStatement(
478-
processInlineRef(context.bindingMetadata, value.content)
479+
processInlineRef(context, value.content)
479480
)
480481
}
481482
}
@@ -894,15 +895,28 @@ function isComponentTag(tag: string) {
894895
}
895896

896897
function processInlineRef(
897-
bindings: BindingMetadata,
898+
context: TransformContext,
898899
raw: string
899900
): JSChildNode[] {
900901
const body = [createSimpleExpression(`_refs['${raw}'] = _value`)]
901-
const type = bindings[raw]
902+
const { bindingMetadata, helperString } = context
903+
const type = bindingMetadata[raw]
902904
if (type === BindingTypes.SETUP_REF) {
903905
body.push(createSimpleExpression(`${raw}.value = _value`))
906+
} else if (type === BindingTypes.SETUP_MAYBE_REF) {
907+
body.push(
908+
createSimpleExpression(
909+
`${helperString(IS_REF)}(${raw}) && (${raw}.value = _value)`
910+
)
911+
)
904912
} else if (type === BindingTypes.SETUP_LET) {
905-
body.push(createSimpleExpression(`${raw} = _value`))
913+
body.push(
914+
createSimpleExpression(
915+
`${helperString(
916+
IS_REF
917+
)}(${raw}) ? ${raw}.value = _value : ${raw} = _value`
918+
)
919+
)
906920
}
907921
return body
908922
}

0 commit comments

Comments
 (0)