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 }
// 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
}
!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
}
}
+// 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'