From 83d41a26ce31a4f6268473c3fe84d70863620b07 Mon Sep 17 00:00:00 2001 From: ygj6 Date: Fri, 10 Sep 2021 10:50:12 +0800 Subject: [PATCH 1/2] fix(compiler): add the judgment about setup-maybe-ref when generating function ref. --- .../transforms/transformElement.spec.ts | 75 +++++++++++++++++++ .../src/transforms/transformElement.ts | 25 +++++-- 2 files changed, 93 insertions(+), 7 deletions(-) diff --git a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts index 16a4c044322..18af77c927a 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: '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..2f538d59e4b 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,25 @@ function isComponentTag(tag: string) { } function processInlineRef( - bindings: BindingMetadata, + context: TransformContext, raw: string ): JSChildNode[] { const body = [createSimpleExpression(`_refs['${raw}'] = _value`)] - const type = bindings[raw] - if (type === BindingTypes.SETUP_REF) { + const { bindingMetadata, helperString } = context + const type = bindingMetadata[raw] + if ( + type === BindingTypes.SETUP_REF || + type === BindingTypes.SETUP_MAYBE_REF + ) { body.push(createSimpleExpression(`${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 } From 2dcf9e8e371592009ce96f15982ffe8712fcfc87 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 16 Sep 2021 11:29:50 -0400 Subject: [PATCH 2/2] refactor: handle maybe ref edge case --- .../__tests__/transforms/transformElement.spec.ts | 2 +- .../compiler-core/src/transforms/transformElement.ts | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts index 18af77c927a..eb29f346522 100644 --- a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts +++ b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts @@ -1031,7 +1031,7 @@ describe('compiler: element transform', () => { content: `_refs['input'] = _value` }, { - content: 'input.value = _value' + content: '_isRef(input) && (input.value = _value)' } ] } diff --git a/packages/compiler-core/src/transforms/transformElement.ts b/packages/compiler-core/src/transforms/transformElement.ts index 2f538d59e4b..2bc44e83980 100644 --- a/packages/compiler-core/src/transforms/transformElement.ts +++ b/packages/compiler-core/src/transforms/transformElement.ts @@ -901,11 +901,14 @@ function processInlineRef( const body = [createSimpleExpression(`_refs['${raw}'] = _value`)] const { bindingMetadata, helperString } = context const type = bindingMetadata[raw] - if ( - type === BindingTypes.SETUP_REF || - type === BindingTypes.SETUP_MAYBE_REF - ) { + 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(