Skip to content

Commit aad2d26

Browse files
committed
feat: support component
1 parent cce6eb5 commit aad2d26

File tree

2 files changed

+35
-26
lines changed

2 files changed

+35
-26
lines changed

playground/virtual-dom/App.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ defineRender((
7474
onInput={count.value = $event.target.value}
7575
/>
7676
{/* Function Components */}
77-
<component is={Component} />
77+
{Component}
7878
<Comp
7979
v-permission={`"post"`}
8080
v-model_number={count.value}

src/core/transform.ts

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export function transformVueJsxVapor(
1818
) {
1919
const s = new MagicString(code)
2020
const exclude: Node[] = []
21+
let hasTextNode = false
2122
const rootNodes: {
2223
node: Node
2324
postCallbacks: ((() => void) | undefined)[]
@@ -27,28 +28,6 @@ export function transformVueJsxVapor(
2728
walkAST<Node>(babelParse(code, getLang(id)), {
2829
enter(node, parent) {
2930
if (
30-
parent?.type === 'JSXAttribute'
31-
&& node.type === 'JSXExpressionContainer'
32-
) {
33-
if (isJSXExpression(node.expression)) {
34-
rootNodes.unshift({
35-
node: node.expression,
36-
postCallbacks: [],
37-
isAttributeValue: true,
38-
})
39-
postCallbacks = rootNodes[0].postCallbacks
40-
}
41-
else if (
42-
/("|<.*?\/.*?>)/.test(s.sliceNode(node.expression))
43-
) {
44-
rootNodes.unshift({
45-
node: node.expression,
46-
postCallbacks: [],
47-
isAttributeValue: true,
48-
})
49-
}
50-
}
51-
else if (
5231
parent?.type !== 'JSXExpressionContainer'
5332
&& !isJSXExpression(parent)
5433
&& isJSXExpression(node)
@@ -60,6 +39,18 @@ export function transformVueJsxVapor(
6039
})
6140
postCallbacks = rootNodes[0].postCallbacks
6241
}
42+
else if (
43+
(parent?.type === 'JSXAttribute')
44+
&& node.type === 'JSXExpressionContainer'
45+
&& /("|<.*?\/.*?>)/.test(s.sliceNode(node.expression))
46+
) {
47+
rootNodes.unshift({
48+
node: node.expression,
49+
postCallbacks: [],
50+
isAttributeValue: true,
51+
})
52+
postCallbacks = rootNodes[0].postCallbacks
53+
}
6354

6455
if (
6556
node.type === 'JSXElement'
@@ -130,9 +121,19 @@ export function transformVueJsxVapor(
130121
s.removeNode(node),
131122
)
132123
}
133-
else {
134-
s.appendRight(node.start!, '{')
135-
s.appendLeft(node.end!, '}')
124+
else if (!isJSXExpression(node.expression)) {
125+
s.overwrite(node.start!, node.start! + 1, '<component :is="__createTextVNode(')
126+
s.overwrite(node.end! - 1, node.end!, ')" />')
127+
if (
128+
/("|<.*?\/.*?>)/.test(s.sliceNode(node.expression))
129+
) {
130+
rootNodes.unshift({
131+
node: node.expression,
132+
postCallbacks: [],
133+
isAttributeValue: true,
134+
})
135+
}
136+
hasTextNode = true
136137
}
137138
}
138139
},
@@ -182,6 +183,14 @@ export function transformVueJsxVapor(
182183
}
183184
}
184185

186+
if (hasTextNode) {
187+
importSet.add('createTextVNode as _createTextVNode')
188+
importSet.add('toDisplayString as _toDisplayString')
189+
s.prepend(
190+
`const __createTextVNode = (node) => node?.__v_isVNode || typeof node ==='function' ? node: _createTextVNode(_toDisplayString(node));`,
191+
)
192+
}
193+
185194
s.prepend(
186195
`import { ${Array.from(importSet).join(', ')} } from ${runtime};`,
187196
)

0 commit comments

Comments
 (0)