Skip to content

Commit e349607

Browse files
committed
fix: use destructure handler for v-for
1 parent cd708d1 commit e349607

File tree

1 file changed

+22
-5
lines changed

1 file changed

+22
-5
lines changed

src/utils/template.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { AttributeNode, DirectiveNode, ExpressionNode, ParentNode, RootNode, SourceLocation, TemplateChildNode, TextNode } from '@vue/compiler-dom'
1+
import type { AttributeNode, DirectiveNode, ExpressionNode, ForParseResult, ParentNode, RootNode, SourceLocation, TemplateChildNode, TextNode } from '@vue/compiler-dom'
22

33
// copy from `@vue/compiler-dom`
44
enum NodeTypes {
@@ -40,6 +40,7 @@ enum NodeTypes {
4040
interface ExpressionTrack {
4141
type: NodeTypes
4242
name?: string
43+
forParseResult?: ForParseResult
4344
}
4445

4546
interface Expression {
@@ -254,11 +255,26 @@ const defaultSnippetHandler: SnippetHandler = {
254255
standalone: false,
255256
}
256257

257-
const vSlotSnippetHandler: SnippetHandler = {
258+
const destructureSnippetHandler: SnippetHandler = {
258259
key: (node) => {
260+
const key = `destructure$:${node.src}`
261+
const lastTrack = node.track.at(-1)
259262
const secondLastTrack = node.track.at(-2)
263+
264+
// v-slot:xxx="{ name }"
260265
if (secondLastTrack?.type === NodeTypes.DIRECTIVE && secondLastTrack.name === 'slot') {
261-
return `vSlot$:${node.src}`
266+
return key
267+
}
268+
269+
// v-for="({ name }, key, index) of items"
270+
// ^this ^this ^this ^not this
271+
if (
272+
secondLastTrack?.type === NodeTypes.DIRECTIVE
273+
&& secondLastTrack.name === 'for'
274+
&& secondLastTrack?.forParseResult
275+
&& lastTrack !== secondLastTrack.forParseResult.source
276+
) {
277+
return key
262278
}
263279
return null
264280
},
@@ -274,7 +290,7 @@ const vSlotSnippetHandler: SnippetHandler = {
274290
standalone: true,
275291
}
276292

277-
const snippetHandlers = [vSlotSnippetHandler, defaultSnippetHandler]
293+
const snippetHandlers = [destructureSnippetHandler, defaultSnippetHandler]
278294
function getKey(expression: Expression) {
279295
for (const handler of snippetHandlers) {
280296
const key = handler.key(expression)
@@ -339,7 +355,8 @@ async function transformJsSnippets(expressions: Expression[], transform: (code:
339355

340356
// transform standalone snippets
341357
await Promise.all(standalone.map(async ({ id, handler, nodes }) => {
342-
const line = await transform(handler.prepare(nodes[0], id))
358+
const prepared = handler.prepare(nodes[0], id)
359+
const line = await transform(prepared)
343360

344361
const res = handler.parse(line.trim(), id)
345362
if (!res) {

0 commit comments

Comments
 (0)