]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-core): avoid duplicate keys in codegen with `v-if` (#6689)
author被雨水过滤的空气(Rairn) <958414905@qq.com>
Tue, 8 Nov 2022 03:04:31 +0000 (11:04 +0800)
committerGitHub <noreply@github.com>
Tue, 8 Nov 2022 03:04:31 +0000 (22:04 -0500)
fix #6641

packages/compiler-core/__tests__/transforms/vIf.spec.ts
packages/compiler-core/src/utils.ts

index 5c36885670fa70a0c213bcea418f48f3d86262b9..9ccce811486f9aeb8db336e96ba762c303595b99 100644 (file)
@@ -628,6 +628,24 @@ describe('compiler: v-if', () => {
       expect(branch1.props).toMatchObject(createObjectMatcher({ key: `[0]` }))
     })
 
+    // #6631
+    test('avoid duplicate keys', () => {
+      const {
+        node: { codegenNode }
+      } = parseWithIfTransform(`<div v-if="ok" key="custom_key" v-bind="obj"/>`)
+      const branch1 = codegenNode.consequent as VNodeCall
+      expect(branch1.props).toMatchObject({
+        type: NodeTypes.JS_CALL_EXPRESSION,
+        callee: MERGE_PROPS,
+        arguments: [
+          createObjectMatcher({
+            key: 'custom_key'
+          }),
+          { content: `obj` }
+        ]
+      })
+    })
+
     test('with spaces between branches', () => {
       const {
         node: { codegenNode }
index c9e310fe089436b1bc1084ee7625b491d8ff5298..6a6b03a2ead991ca30f21dbc4c94e79b7e6d6fe1 100644 (file)
@@ -397,7 +397,10 @@ export function injectProp(
     // if doesn't override user provided keys
     const first = props.arguments[0] as string | JSChildNode
     if (!isString(first) && first.type === NodeTypes.JS_OBJECT_EXPRESSION) {
-      first.properties.unshift(prop)
+      // #6631
+      if (!hasProp(prop, first)) {
+        first.properties.unshift(prop)
+      }
     } else {
       if (props.callee === TO_HANDLERS) {
         // #2366
@@ -411,17 +414,7 @@ export function injectProp(
     }
     !propsWithInjection && (propsWithInjection = props)
   } else if (props.type === NodeTypes.JS_OBJECT_EXPRESSION) {
-    let alreadyExists = false
-    // check existing key to avoid overriding user provided keys
-    if (prop.key.type === NodeTypes.SIMPLE_EXPRESSION) {
-      const propKeyName = prop.key.content
-      alreadyExists = props.properties.some(
-        p =>
-          p.key.type === NodeTypes.SIMPLE_EXPRESSION &&
-          p.key.content === propKeyName
-      )
-    }
-    if (!alreadyExists) {
+    if (!hasProp(prop, props)) {
       props.properties.unshift(prop)
     }
     propsWithInjection = props
@@ -453,6 +446,20 @@ export function injectProp(
   }
 }
 
+// check existing key to avoid overriding user provided keys
+function hasProp(prop: Property, props: ObjectExpression) {
+  let result = false
+  if (prop.key.type === NodeTypes.SIMPLE_EXPRESSION) {
+    const propKeyName = prop.key.content
+    result = props.properties.some(
+      p =>
+        p.key.type === NodeTypes.SIMPLE_EXPRESSION &&
+        p.key.content === propKeyName
+    )
+  }
+  return result
+}
+
 export function toValidAssetId(
   name: string,
   type: 'component' | 'directive' | 'filter'