fix(compiler-core): fix v-if key injection with v-on object syntax (#2368)

fix #2366
This commit is contained in:
ᴜɴвʏтᴇ 2020-10-14 00:04:52 +08:00 committed by GitHub
parent 6ba7ba47d5
commit 692197be33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 15 deletions

View File

@ -4,25 +4,25 @@ import { transformIf } from '../../src/transforms/vIf'
import { transformElement } from '../../src/transforms/transformElement'
import { transformSlotOutlet } from '../../src/transforms/transformSlotOutlet'
import {
CommentNode,
ConditionalExpression,
ElementNode,
ElementTypes,
IfBranchNode,
IfConditionalExpression,
IfNode,
NodeTypes,
ElementNode,
TextNode,
CommentNode,
SimpleExpressionNode,
ConditionalExpression,
IfConditionalExpression,
VNodeCall,
ElementTypes,
IfBranchNode
TextNode,
VNodeCall
} from '../../src/ast'
import { ErrorCodes } from '../../src/errors'
import { CompilerOptions, generate } from '../../src'
import { CompilerOptions, generate, TO_HANDLERS } from '../../src'
import {
CREATE_COMMENT,
FRAGMENT,
MERGE_PROPS,
RENDER_SLOT,
CREATE_COMMENT
RENDER_SLOT
} from '../../src/runtimeHelpers'
import { createObjectMatcher } from '../testUtils'
@ -673,4 +673,24 @@ describe('compiler: v-if', () => {
expect((b1.children[3] as ElementNode).tag).toBe(`p`)
})
})
test('v-on with v-if', () => {
const {
node: { codegenNode }
} = parseWithIfTransform(
`<button v-on="{ click: clickEvent }" v-if="true">w/ v-if</button>`
)
expect((codegenNode.consequent as any).props.type).toBe(
NodeTypes.JS_CALL_EXPRESSION
)
expect((codegenNode.consequent as any).props.callee).toBe(MERGE_PROPS)
expect(
(codegenNode.consequent as any).props.arguments[0].properties[0].value
.content
).toBe('0')
expect((codegenNode.consequent as any).props.arguments[1].callee).toBe(
TO_HANDLERS
)
})
})

View File

@ -29,7 +29,8 @@ import {
TELEPORT,
SUSPENSE,
KEEP_ALIVE,
BASE_TRANSITION
BASE_TRANSITION,
TO_HANDLERS
} from './runtimeHelpers'
import { isString, isObject, hyphenate, extend } from '@vue/shared'
@ -215,7 +216,7 @@ export function injectProp(
prop: Property,
context: TransformContext
) {
let propsWithInjection: ObjectExpression | CallExpression
let propsWithInjection: ObjectExpression | CallExpression | undefined
const props =
node.type === NodeTypes.VNODE_CALL ? node.props : node.arguments[2]
if (props == null || isString(props)) {
@ -228,9 +229,17 @@ export function injectProp(
if (!isString(first) && first.type === NodeTypes.JS_OBJECT_EXPRESSION) {
first.properties.unshift(prop)
} else {
props.arguments.unshift(createObjectExpression([prop]))
if (props.callee === TO_HANDLERS) {
// #2366
propsWithInjection = createCallExpression(context.helper(MERGE_PROPS), [
createObjectExpression([prop]),
props
])
} else {
props.arguments.unshift(createObjectExpression([prop]))
}
}
propsWithInjection = props
!propsWithInjection && (propsWithInjection = props)
} else if (props.type === NodeTypes.JS_OBJECT_EXPRESSION) {
let alreadyExists = false
// check existing key to avoid overriding user provided keys