Skip to content

Commit

Permalink
fix(compiler-core): avoid duplicate keys in codegen with v-if (vuej…
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangzhonghe authored and chrislone committed Feb 4, 2023
1 parent a61c569 commit 3c9e2ed
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 12 deletions.
18 changes: 18 additions & 0 deletions packages/compiler-core/__tests__/transforms/vIf.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
31 changes: 19 additions & 12 deletions packages/compiler-core/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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'
Expand Down

0 comments on commit 3c9e2ed

Please sign in to comment.