mirror of https://github.com/vuejs/core.git
fix(compiler-core): fix :key shorthand on v-for (#10942)
close #10882 close #10939
This commit is contained in:
parent
f94568b2b7
commit
29425df1ac
|
@ -18,7 +18,7 @@ import {
|
|||
import { ErrorCodes } from '../../src/errors'
|
||||
import { type CompilerOptions, generate } from '../../src'
|
||||
import { FRAGMENT, RENDER_LIST, RENDER_SLOT } from '../../src/runtimeHelpers'
|
||||
import { PatchFlags } from '@vue/shared'
|
||||
import { PatchFlagNames, PatchFlags } from '@vue/shared'
|
||||
import { createObjectMatcher, genFlagText } from '../testUtils'
|
||||
|
||||
export function parseWithForTransform(
|
||||
|
@ -1043,5 +1043,33 @@ describe('compiler: v-for', () => {
|
|||
})
|
||||
expect(generate(root).code).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test('template v-for key w/ :key shorthand on div', () => {
|
||||
const {
|
||||
node: { codegenNode },
|
||||
} = parseWithForTransform('<div v-for="key in keys" :key>test</div>')
|
||||
expect(codegenNode.patchFlag).toBe(
|
||||
`${PatchFlags.KEYED_FRAGMENT} /* ${PatchFlagNames[PatchFlags.KEYED_FRAGMENT]} */`,
|
||||
)
|
||||
})
|
||||
|
||||
test('template v-for key w/ :key shorthand on template injected to the child', () => {
|
||||
const {
|
||||
node: { codegenNode },
|
||||
} = parseWithForTransform(
|
||||
'<template v-for="key in keys" :key><div>test</div></template>',
|
||||
)
|
||||
expect(assertSharedCodegen(codegenNode, true)).toMatchObject({
|
||||
source: { content: `keys` },
|
||||
params: [{ content: `key` }],
|
||||
innerVNodeCall: {
|
||||
type: NodeTypes.VNODE_CALL,
|
||||
tag: `"div"`,
|
||||
props: createObjectMatcher({
|
||||
key: '[key]',
|
||||
}),
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import type { DirectiveTransform } from '../transform'
|
||||
import type { DirectiveTransform, TransformContext } from '../transform'
|
||||
import {
|
||||
type DirectiveNode,
|
||||
type ExpressionNode,
|
||||
NodeTypes,
|
||||
type SimpleExpressionNode,
|
||||
|
@ -56,11 +57,8 @@ export const transformBind: DirectiveTransform = (dir, _node, context) => {
|
|||
}
|
||||
}
|
||||
|
||||
const propName = camelize((arg as SimpleExpressionNode).content)
|
||||
exp = dir.exp = createSimpleExpression(propName, false, arg.loc)
|
||||
if (!__BROWSER__) {
|
||||
exp = dir.exp = processExpression(exp, context)
|
||||
}
|
||||
transformBindShorthand(dir, context)
|
||||
exp = dir.exp!
|
||||
}
|
||||
|
||||
if (arg.type !== NodeTypes.SIMPLE_EXPRESSION) {
|
||||
|
@ -98,6 +96,19 @@ export const transformBind: DirectiveTransform = (dir, _node, context) => {
|
|||
}
|
||||
}
|
||||
|
||||
export const transformBindShorthand = (
|
||||
dir: DirectiveNode,
|
||||
context: TransformContext,
|
||||
) => {
|
||||
const arg = dir.arg!
|
||||
|
||||
const propName = camelize((arg as SimpleExpressionNode).content)
|
||||
dir.exp = createSimpleExpression(propName, false, arg.loc)
|
||||
if (!__BROWSER__) {
|
||||
dir.exp = processExpression(dir.exp, context)
|
||||
}
|
||||
}
|
||||
|
||||
const injectPrefix = (arg: ExpressionNode, prefix: string) => {
|
||||
if (arg.type === NodeTypes.SIMPLE_EXPRESSION) {
|
||||
if (arg.isStatic) {
|
||||
|
|
|
@ -47,6 +47,7 @@ import {
|
|||
import { processExpression } from './transformExpression'
|
||||
import { validateBrowserExpression } from '../validateExpression'
|
||||
import { PatchFlagNames, PatchFlags } from '@vue/shared'
|
||||
import { transformBindShorthand } from './vBind'
|
||||
|
||||
export const transformFor = createStructuralDirectiveTransform(
|
||||
'for',
|
||||
|
@ -60,13 +61,20 @@ export const transformFor = createStructuralDirectiveTransform(
|
|||
]) as ForRenderListExpression
|
||||
const isTemplate = isTemplateNode(node)
|
||||
const memo = findDir(node, 'memo')
|
||||
const keyProp = findProp(node, `key`)
|
||||
const keyProp = findProp(node, `key`, false, true)
|
||||
if (keyProp && keyProp.type === NodeTypes.DIRECTIVE && !keyProp.exp) {
|
||||
// resolve :key shorthand #10882
|
||||
transformBindShorthand(keyProp, context)
|
||||
}
|
||||
const keyExp =
|
||||
keyProp &&
|
||||
(keyProp.type === NodeTypes.ATTRIBUTE
|
||||
? createSimpleExpression(keyProp.value!.content, true)
|
||||
: keyProp.exp!)
|
||||
const keyProperty = keyProp ? createObjectProperty(`key`, keyExp!) : null
|
||||
? keyProp.value
|
||||
? createSimpleExpression(keyProp.value.content, true)
|
||||
: undefined
|
||||
: keyProp.exp)
|
||||
const keyProperty =
|
||||
keyProp && keyExp ? createObjectProperty(`key`, keyExp) : null
|
||||
|
||||
if (!__BROWSER__ && isTemplate) {
|
||||
// #2085 / #5288 process :key and v-memo expressions need to be
|
||||
|
|
Loading…
Reference in New Issue