From 0cef65cee411356e721bbc90d731fc52fc8fce94 Mon Sep 17 00:00:00 2001 From: yangxiuxiu <79584569+yangxiuxiu1115@users.noreply.github.com> Date: Mon, 15 Apr 2024 21:18:59 +0800 Subject: [PATCH] fix(compiler-sfc): fix defineModel coercion for boolean + string union types (#9603) close #9587 close #10676 --- .../__snapshots__/defineModel.spec.ts.snap | 20 +++++++++++++++++++ .../compileScript/defineModel.spec.ts | 20 +++++++++++++++++++ .../compiler-sfc/src/script/defineModel.ts | 18 ++++++++++------- 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineModel.spec.ts.snap b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineModel.spec.ts.snap index b6a93541d36..6e9967fd011 100644 --- a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineModel.spec.ts.snap +++ b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineModel.spec.ts.snap @@ -103,6 +103,26 @@ return { modelValue } })" `; +exports[`defineModel() > w/ Boolean And Function types, production mode 1`] = ` +"import { useModel as _useModel, defineComponent as _defineComponent } from 'vue' + +export default /*#__PURE__*/_defineComponent({ + props: { + "modelValue": { type: [Boolean, String] }, + "modelModifiers": {}, + }, + emits: ["update:modelValue"], + setup(__props, { expose: __expose }) { + __expose(); + + const modelValue = _useModel(__props, "modelValue") + +return { modelValue } +} + +})" +`; + exports[`defineModel() > w/ array props 1`] = ` "import { useModel as _useModel, mergeModels as _mergeModels } from 'vue' diff --git a/packages/compiler-sfc/__tests__/compileScript/defineModel.spec.ts b/packages/compiler-sfc/__tests__/compileScript/defineModel.spec.ts index 304258615a8..bd048a847e4 100644 --- a/packages/compiler-sfc/__tests__/compileScript/defineModel.spec.ts +++ b/packages/compiler-sfc/__tests__/compileScript/defineModel.spec.ts @@ -221,4 +221,24 @@ describe('defineModel()', () => { assertCode(content) expect(content).toMatch(`set: (v) => { return v + __props.x }`) }) + + test('w/ Boolean And Function types, production mode', () => { + const { content, bindings } = compile( + ` + + `, + { isProd: true }, + ) + assertCode(content) + expect(content).toMatch('"modelValue": { type: [Boolean, String] }') + expect(content).toMatch('emits: ["update:modelValue"]') + expect(content).toMatch( + `const modelValue = _useModel(__props, "modelValue")`, + ) + expect(bindings).toStrictEqual({ + modelValue: BindingTypes.SETUP_REF, + }) + }) }) diff --git a/packages/compiler-sfc/src/script/defineModel.ts b/packages/compiler-sfc/src/script/defineModel.ts index 24fd0780eaa..e5e2ed0e53f 100644 --- a/packages/compiler-sfc/src/script/defineModel.ts +++ b/packages/compiler-sfc/src/script/defineModel.ts @@ -129,15 +129,19 @@ export function genModelProps(ctx: ScriptCompileContext) { let runtimeTypes = type && inferRuntimeType(ctx, type) if (runtimeTypes) { + const hasBoolean = runtimeTypes.includes('Boolean') const hasUnknownType = runtimeTypes.includes(UNKNOWN_TYPE) - runtimeTypes = runtimeTypes.filter(el => { - if (el === UNKNOWN_TYPE) return false - return isProd - ? el === 'Boolean' || (el === 'Function' && options) - : true - }) - skipCheck = !isProd && hasUnknownType && runtimeTypes.length > 0 + if (isProd || hasUnknownType) { + runtimeTypes = runtimeTypes.filter( + t => + t === 'Boolean' || + (hasBoolean && t === 'String') || + (t === 'Function' && options), + ) + + skipCheck = !isProd && hasUnknownType && runtimeTypes.length > 0 + } } let runtimeType =