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`
44enum NodeTypes {
@@ -40,6 +40,7 @@ enum NodeTypes {
4040interface ExpressionTrack {
4141 type : NodeTypes
4242 name ?: string
43+ forParseResult ?: ForParseResult
4344}
4445
4546interface 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 ]
278294function 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