7
7
parseSFC ,
8
8
walkAST ,
9
9
} 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'
11
11
import { compile } from 'vue/vapor'
12
+ import { transformVFor } from './v-for'
12
13
13
14
export function transformVueJsxVapor ( code : string , id : string ) {
14
15
const lang = getLang ( id )
@@ -35,71 +36,91 @@ export function transformVueJsxVapor(code: string, id: string) {
35
36
}
36
37
37
38
const s = new MagicString ( code )
39
+ const importSet = new Set ( )
38
40
for ( const { ast, offset } of asts ) {
39
41
const rootElements : ( JSXElement | JSXFragment ) [ ] = [ ]
42
+ const vForNodes : CallExpression [ ] = [ ]
40
43
walkAST < Node > ( ast , {
41
44
enter ( node , parent ) {
42
- if ( node . type === 'JSXElement' ) {
43
- if (
45
+ if (
46
+ ( node . type === 'JSXElement'
47
+ && (
44
48
parent ?. type === 'VariableDeclarator'
45
49
|| parent ?. type === 'ArrowFunctionExpression'
46
50
|| parent ?. type === 'CallExpression'
47
51
|| parent ?. type === 'ReturnStatement'
48
- )
49
- rootElements . push ( node )
52
+ ) )
53
+ || node . type === 'JSXFragment'
54
+ ) {
55
+ rootElements . push ( node )
56
+ this . skip ( )
57
+ }
58
+ } ,
59
+ } )
50
60
61
+ for ( const rootElement of rootElements ) {
62
+ walkAST < Node > ( rootElement , {
63
+ enter ( node , parent ) {
51
64
if (
52
- node . openingElement . attributes . find (
65
+ node . type === 'JSXElement'
66
+ && node . openingElement . attributes . find (
53
67
attr =>
54
68
attr . type === 'JSXAttribute'
55
69
&& s . sliceNode ( attr . name , { offset } ) === 'v-pre' ,
56
70
)
57
- )
71
+ ) {
58
72
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
- )
70
73
}
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
+ }
73
90
}
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
+ } )
77
105
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 ,
81
109
`"${
82
110
s . slice (
83
111
node . value . start ! + offset + 1 ,
84
112
node . value . end ! + offset - 1 ,
85
113
)
86
114
} "`,
87
115
{ offset } ,
88
- )
116
+ )
117
+ }
89
118
}
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 )
100
123
101
- const importSet = new Set ( )
102
- for ( const rootElement of rootElements ) {
103
124
const { code } = compile (
104
125
s . sliceNode (
105
126
rootElement . type === 'JSXFragment'
0 commit comments