diff --git a/packages/compiler-dom/__tests__/transforms/vModel.spec.ts b/packages/compiler-dom/__tests__/transforms/vModel.spec.ts
index dce8f09b02c..a67ca5d691f 100644
--- a/packages/compiler-dom/__tests__/transforms/vModel.spec.ts
+++ b/packages/compiler-dom/__tests__/transforms/vModel.spec.ts
@@ -137,6 +137,27 @@ describe('compiler: transform v-model', () => {
})
)
})
+
+ test('should error on dynamic value binding alongside v-model', () => {
+ const onError = vi.fn()
+ transformWithModel(``, {
+ onError
+ })
+ expect(onError).toHaveBeenCalledWith(
+ expect.objectContaining({
+ code: DOMErrorCodes.X_V_MODEL_UNNECESSARY_VALUE
+ })
+ )
+ })
+
+ // #3596
+ test('should NOT error on static value binding alongside v-model', () => {
+ const onError = vi.fn()
+ transformWithModel(``, {
+ onError
+ })
+ expect(onError).not.toHaveBeenCalled()
+ })
})
describe('modifiers', () => {
diff --git a/packages/compiler-dom/src/transforms/vModel.ts b/packages/compiler-dom/src/transforms/vModel.ts
index 5dff390d3d8..bc1f6fcd27b 100644
--- a/packages/compiler-dom/src/transforms/vModel.ts
+++ b/packages/compiler-dom/src/transforms/vModel.ts
@@ -4,7 +4,9 @@ import {
ElementTypes,
findProp,
NodeTypes,
- hasDynamicKeyVBind
+ hasDynamicKeyVBind,
+ findDir,
+ isStaticArgOf
} from '@vue/compiler-core'
import { createDOMCompilerError, DOMErrorCodes } from '../errors'
import {
@@ -32,8 +34,8 @@ export const transformModel: DirectiveTransform = (dir, node, context) => {
}
function checkDuplicatedValue() {
- const value = findProp(node, 'value')
- if (value) {
+ const value = findDir(node, 'bind')
+ if (value && isStaticArgOf(value.arg, 'value')) {
context.onError(
createDOMCompilerError(
DOMErrorCodes.X_V_MODEL_UNNECESSARY_VALUE,