From f29d0611246bb619df2e46b30dfd5e43ad4ee6b1 Mon Sep 17 00:00:00 2001 From: ygj6 <7699524+ygj6@users.noreply.github.com> Date: Thu, 16 Sep 2021 23:33:16 +0800 Subject: [PATCH] fix(compiler): fix template ref codegen for setup-maybe-ref binding types (#4549) fix #4546 --- .../transforms/transformElement.spec.ts | 75 +++++++++++++++++++ .../src/transforms/transformElement.ts | 26 +++++-- 2 files changed, 95 insertions(+), 6 deletions(-) diff --git a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts index 16a4c044322..eb29f346522 100644 --- a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts +++ b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts @@ -1004,6 +1004,81 @@ describe('compiler: element transform', () => { }) }) + test('the binding not exists (inline maybe ref input)', () => { + const { node } = parseWithElementTransform(``, { + inline: true, + bindingMetadata: { + input: BindingTypes.SETUP_MAYBE_REF + } + }) + expect(node.props).toMatchObject({ + type: NodeTypes.JS_OBJECT_EXPRESSION, + properties: [ + { + type: NodeTypes.JS_PROPERTY, + key: { + type: NodeTypes.SIMPLE_EXPRESSION, + content: 'ref', + isStatic: true + }, + value: { + type: NodeTypes.JS_FUNCTION_EXPRESSION, + params: ['_value', '_refs'], + body: { + type: NodeTypes.JS_BLOCK_STATEMENT, + body: [ + { + content: `_refs['input'] = _value` + }, + { + content: '_isRef(input) && (input.value = _value)' + } + ] + } + } + } + ] + }) + }) + + test('the binding not exists (inline let ref input)', () => { + const { node } = parseWithElementTransform(``, { + inline: true, + bindingMetadata: { + input: BindingTypes.SETUP_LET + } + }) + expect(node.props).toMatchObject({ + type: NodeTypes.JS_OBJECT_EXPRESSION, + properties: [ + { + type: NodeTypes.JS_PROPERTY, + key: { + type: NodeTypes.SIMPLE_EXPRESSION, + content: 'ref', + isStatic: true + }, + value: { + type: NodeTypes.JS_FUNCTION_EXPRESSION, + params: ['_value', '_refs'], + body: { + type: NodeTypes.JS_BLOCK_STATEMENT, + body: [ + { + content: `_refs['input'] = _value` + }, + { + content: + '_isRef(input) ? input.value = _value : input = _value' + } + ] + } + } + } + ] + }) + }) + test('HYDRATE_EVENTS', () => { // ignore click events (has dedicated fast path) const { node } = parseWithElementTransform(`
`, { diff --git a/packages/compiler-core/src/transforms/transformElement.ts b/packages/compiler-core/src/transforms/transformElement.ts index c471d2a4b84..2bc44e83980 100644 --- a/packages/compiler-core/src/transforms/transformElement.ts +++ b/packages/compiler-core/src/transforms/transformElement.ts @@ -48,7 +48,8 @@ import { KEEP_ALIVE, SUSPENSE, UNREF, - GUARD_REACTIVE_PROPS + GUARD_REACTIVE_PROPS, + IS_REF } from '../runtimeHelpers' import { getInnerRange, @@ -61,7 +62,7 @@ import { } from '../utils' import { buildSlots } from './vSlot' import { getConstantType } from './hoistStatic' -import { BindingMetadata, BindingTypes } from '../options' +import { BindingTypes } from '../options' import { checkCompatEnabled, CompilerDeprecationTypes, @@ -475,7 +476,7 @@ export function buildProps( if (!__BROWSER__ && context.inline && value?.content) { valueNode = createFunctionExpression(['_value', '_refs']) valueNode.body = createBlockStatement( - processInlineRef(context.bindingMetadata, value.content) + processInlineRef(context, value.content) ) } } @@ -894,15 +895,28 @@ function isComponentTag(tag: string) { } function processInlineRef( - bindings: BindingMetadata, + context: TransformContext, raw: string ): JSChildNode[] { const body = [createSimpleExpression(`_refs['${raw}'] = _value`)] - const type = bindings[raw] + const { bindingMetadata, helperString } = context + const type = bindingMetadata[raw] if (type === BindingTypes.SETUP_REF) { body.push(createSimpleExpression(`${raw}.value = _value`)) + } else if (type === BindingTypes.SETUP_MAYBE_REF) { + body.push( + createSimpleExpression( + `${helperString(IS_REF)}(${raw}) && (${raw}.value = _value)` + ) + ) } else if (type === BindingTypes.SETUP_LET) { - body.push(createSimpleExpression(`${raw} = _value`)) + body.push( + createSimpleExpression( + `${helperString( + IS_REF + )}(${raw}) ? ${raw}.value = _value : ${raw} = _value` + ) + ) } return body }