77 parseSFC ,
88 walkAST ,
99} from '@vue-macros/common'
10- import type { JSXElement , JSXFragment , Node , Program } from '@babel/types'
10+ import type { CallExpression , JSXElement , JSXFragment , Node , Program } from '@babel/types'
1111import { compile } from 'vue/vapor'
12+ import { transformVFor } from './v-for'
1213
1314export function transformVueJsxVapor ( code : string , id : string ) {
1415 const lang = getLang ( id )
@@ -35,71 +36,91 @@ export function transformVueJsxVapor(code: string, id: string) {
3536 }
3637
3738 const s = new MagicString ( code )
39+ const importSet = new Set ( )
3840 for ( const { ast, offset } of asts ) {
3941 const rootElements : ( JSXElement | JSXFragment ) [ ] = [ ]
42+ const vForNodes : CallExpression [ ] = [ ]
4043 walkAST < Node > ( ast , {
4144 enter ( node , parent ) {
42- if ( node . type === 'JSXElement' ) {
43- if (
45+ if (
46+ ( node . type === 'JSXElement'
47+ && (
4448 parent ?. type === 'VariableDeclarator'
4549 || parent ?. type === 'ArrowFunctionExpression'
4650 || parent ?. type === 'CallExpression'
4751 || parent ?. type === 'ReturnStatement'
48- )
49- rootElements . push ( node )
52+ ) )
53+ || node . type === 'JSXFragment'
54+ ) {
55+ rootElements . push ( node )
56+ this . skip ( )
57+ }
58+ } ,
59+ } )
5060
61+ for ( const rootElement of rootElements ) {
62+ walkAST < Node > ( rootElement , {
63+ enter ( node , parent ) {
5164 if (
52- node . openingElement . attributes . find (
65+ node . type === 'JSXElement'
66+ && node . openingElement . attributes . find (
5367 attr =>
5468 attr . type === 'JSXAttribute'
5569 && s . sliceNode ( attr . name , { offset } ) === 'v-pre' ,
5670 )
57- )
71+ ) {
5872 return this . skip ( )
59- }
60- else if ( node . type === 'JSXFragment' ) {
61- rootElements . push ( node )
62- }
63- else if ( node . type === 'JSXAttribute' ) {
64- let name = s . sliceNode ( node . name , { offset } )
65- if ( / ^ o n [ A - Z ] / . test ( name ) ) {
66- name = name . replace (
67- / ^ ( o n ) ( [ A - Z ] ) / ,
68- ( _ , __ , str ) => `@${ str . toLowerCase ( ) } ` ,
69- )
7073 }
71- else if ( ! name . startsWith ( 'v-' ) ) {
72- name = `:${ name } `
74+ else if (
75+ node . type === 'JSXExpressionContainer'
76+ && parent ?. type === 'JSXElement'
77+ ) {
78+ if ( node . expression . type === 'CallExpression'
79+ && node . expression . callee . type === 'MemberExpression'
80+ && node . expression . callee . property . type === 'Identifier'
81+ && node . expression . callee . property . name === 'map' ) {
82+ vForNodes . push ( node . expression )
83+ s . remove ( node . start ! + offset , node . expression . start ! + offset )
84+ s . remove ( node . expression . end ! + offset , node . end ! + offset )
85+ }
86+ else {
87+ s . appendLeft ( node . start ! + offset , '{' )
88+ s . appendRight ( node . end ! + offset , '}' )
89+ }
7390 }
74- s . overwriteNode ( node . name , `${ name . replaceAll ( '_' , '.' ) } ` , {
75- offset,
76- } )
91+ else if ( node . type === 'JSXAttribute' ) {
92+ let name = s . sliceNode ( node . name , { offset } )
93+ if ( / ^ o n [ A - Z ] / . test ( name ) ) {
94+ name = name . replace (
95+ / ^ ( o n ) ( [ A - Z ] ) / ,
96+ ( _ , __ , str ) => `@${ str . toLowerCase ( ) } ` ,
97+ )
98+ }
99+ else if ( ! name . startsWith ( 'v-' ) ) {
100+ name = `:${ name } `
101+ }
102+ s . overwriteNode ( node . name , `${ name . replaceAll ( '_' , '.' ) } ` , {
103+ offset,
104+ } )
77105
78- if ( node . value && node . value . type !== 'StringLiteral' ) {
79- s . overwriteNode (
80- node . value ,
106+ if ( node . value && node . value . type !== 'StringLiteral' ) {
107+ s . overwriteNode (
108+ node . value ,
81109 `"${
82110 s . slice (
83111 node . value . start ! + offset + 1 ,
84112 node . value . end ! + offset - 1 ,
85113 )
86114 } "`,
87115 { offset } ,
88- )
116+ )
117+ }
89118 }
90- }
91- else if (
92- node . type === 'JSXExpressionContainer'
93- && parent ?. type === 'JSXElement'
94- ) {
95- s . appendLeft ( node . start ! + offset , '{' )
96- s . appendRight ( node . end ! + offset , '}' )
97- }
98- } ,
99- } )
119+ } ,
120+ } )
121+
122+ transformVFor ( vForNodes , s , offset )
100123
101- const importSet = new Set ( )
102- for ( const rootElement of rootElements ) {
103124 const { code } = compile (
104125 s . sliceNode (
105126 rootElement . type === 'JSXFragment'
0 commit comments