]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler/v-model): catch incorrect v-model usage on prop bindings
authorEvan You <yyx990803@gmail.com>
Thu, 10 Nov 2022 02:42:27 +0000 (10:42 +0800)
committerEvan You <yyx990803@gmail.com>
Thu, 10 Nov 2022 02:42:27 +0000 (10:42 +0800)
close #5584

packages/compiler-core/__tests__/transforms/vModel.spec.ts
packages/compiler-core/src/errors.ts
packages/compiler-core/src/transforms/vModel.ts

index 96dbe2cb5fb98d3195b8cb4c8a8e7b07a5624538..0af7d9eb608165b58fdb58e547106cbc118a0bc6 100644 (file)
@@ -10,7 +10,8 @@ import {
   ComponentNode,
   NodeTypes,
   VNodeCall,
-  NORMALIZE_PROPS
+  NORMALIZE_PROPS,
+  BindingTypes
 } from '../../src'
 import { ErrorCodes } from '../../src/errors'
 import { transformModel } from '../../src/transforms/vModel'
@@ -561,5 +562,22 @@ describe('compiler: transform v-model', () => {
         })
       )
     })
+
+    test('used on props', () => {
+      const onError = jest.fn()
+      parseWithVModel('<div v-model="p" />', {
+        onError,
+        bindingMetadata: {
+          p: BindingTypes.PROPS
+        }
+      })
+
+      expect(onError).toHaveBeenCalledTimes(1)
+      expect(onError).toHaveBeenCalledWith(
+        expect.objectContaining({
+          code: ErrorCodes.X_V_MODEL_ON_SCOPE_VARIABLE
+        })
+      )
+    })
   })
 })
index f0af09dda31c74b738ef2dbc74eee6b3822ad4a0..345aa183fc914e912d25dbd11edc467319be282f 100644 (file)
@@ -87,6 +87,7 @@ export const enum ErrorCodes {
   X_V_MODEL_NO_EXPRESSION,
   X_V_MODEL_MALFORMED_EXPRESSION,
   X_V_MODEL_ON_SCOPE_VARIABLE,
+  X_V_MODEL_ON_PROPS,
   X_INVALID_EXPRESSION,
   X_KEEP_ALIVE_INVALID_CHILDREN,
 
@@ -168,6 +169,7 @@ export const errorMessages: Record<ErrorCodes, string> = {
   [ErrorCodes.X_V_MODEL_NO_EXPRESSION]: `v-model is missing expression.`,
   [ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION]: `v-model value must be a valid JavaScript member expression.`,
   [ErrorCodes.X_V_MODEL_ON_SCOPE_VARIABLE]: `v-model cannot be used on v-for or v-slot scope variables because they are not writable.`,
+  [ErrorCodes.X_V_MODEL_ON_PROPS]: `v-model cannot be used on a prop, because local prop bindings are not writable.\nUse a v-bind binding combined with a v-on listener that emits update:x event instead.`,
   [ErrorCodes.X_INVALID_EXPRESSION]: `Error parsing JavaScript expression: `,
   [ErrorCodes.X_KEEP_ALIVE_INVALID_CHILDREN]: `<KeepAlive> expects exactly one child component.`,
 
index bcf3749bdfe81e622c4586f758bbc1e56e3ae5e9..16995994699d3f68513c57c1c71c6a695bbea61f 100644 (file)
@@ -35,6 +35,16 @@ export const transformModel: DirectiveTransform = (dir, node, context) => {
   // im SFC <script setup> inline mode, the exp may have been transformed into
   // _unref(exp)
   const bindingType = context.bindingMetadata[rawExp]
+
+  // check props
+  if (
+    bindingType === BindingTypes.PROPS ||
+    bindingType === BindingTypes.PROPS_ALIASED
+  ) {
+    context.onError(createCompilerError(ErrorCodes.X_V_MODEL_ON_PROPS, exp.loc))
+    return createTransformProps()
+  }
+
   const maybeRef =
     !__BROWSER__ &&
     context.inline &&