Skip to content
Permalink
Browse files
fix(compiler-core): avoid duplicate keys in codegen with v-if (#6689)
fix #6641
  • Loading branch information
zhangzhonghe committed Nov 8, 2022
1 parent 2a9996c commit 640cfce4ff808fdfc419058f39a2ff4874a25899
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 12 deletions.
@@ -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 }
@@ -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'

0 comments on commit 640cfce

Please sign in to comment.