Skip to content

Commit e45feb7

Browse files
committed
feat(compiler): support conditional & logical expression
1 parent f7889a1 commit e45feb7

File tree

17 files changed

+534
-71
lines changed

17 files changed

+534
-71
lines changed

.changeset/tidy-dryers-yawn.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'unplugin-vue-jsx-vapor': patch
3+
---
4+
5+
support conditional & logical expression

.github/workflows/release.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ on:
44
push:
55
branches:
66
- main
7-
- beta
87

98
concurrency: ${{ github.workflow }}-${{ github.ref }}
109

.vscode/settings.json

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,3 @@
11
{
2-
// Enable the ESlint flat config support
3-
"eslint.experimental.useFlatConfig": true,
4-
"eslint.runtime": null,
5-
6-
// Disable the default formatter, use eslint instead
7-
"prettier.enable": false,
8-
"editor.formatOnSave": false,
9-
10-
// Auto fix
11-
"editor.codeActionsOnSave": {
12-
"source.fixAll": "explicit",
13-
"source.organizeImports": "never"
14-
},
15-
16-
// Silent the stylistic rules in you IDE, but still auto fix them
17-
"eslint.rules.customizations": [
18-
{ "rule": "style/*", "severity": "off" },
19-
{ "rule": "*-indent", "severity": "off" },
20-
{ "rule": "*-spacing", "severity": "off" },
21-
{ "rule": "*-spaces", "severity": "off" },
22-
{ "rule": "*-order", "severity": "off" },
23-
{ "rule": "*-dangle", "severity": "off" },
24-
{ "rule": "*-newline", "severity": "off" },
25-
{ "rule": "*quotes", "severity": "off" },
26-
{ "rule": "*semi", "severity": "off" }
27-
],
28-
29-
// Enable eslint for all supported languages
30-
"eslint.validate": [
31-
"javascript",
32-
"javascriptreact",
33-
"typescript",
34-
"typescriptreact",
35-
"vue",
36-
"html",
37-
"markdown",
38-
"json",
39-
"jsonc",
40-
"yaml"
41-
]
2+
"eslint.experimental.useFlatConfig": true
423
}

eslint.config.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { sxzz } from '@sxzz/eslint-config'
22

33
export default sxzz({
4-
ignores: ['playground'],
54
rules: {
65
'unicorn/filename-case': 'off',
76
'import/no-default-export': 'off',

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@
126126
"dependencies": {
127127
"@babel/parser": "^7.24.7",
128128
"@vue-macros/common": "^1.10.4",
129+
"@vue-vapor/compiler-core": "3.2024.0-4c28469",
129130
"@vue-vapor/compiler-dom": "3.2024.0-63dbc26",
130131
"@vue-vapor/compiler-vapor": "3.2024.0-63dbc26",
131132
"@vue-vapor/runtime-vapor": "3.2024.0-63dbc26",

playground/App.vue

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
<script lang="tsx">
22
import { defineComponent, ref } from 'vue'
33
import Count2 from './Count.vue'
4+
import If from './if.vue'
45
56
export default defineComponent({
67
setup() {
7-
const count = ref(1)
8+
const count = ref('1')
89
910
const Count = (props) => {
1011
return <div>{props.value}</div>
@@ -16,14 +17,22 @@ export default defineComponent({
1617
1718
return (
1819
<>
19-
<input
20-
value_prop={count.value}
21-
onInput={(e) => (count.value = e.target.value)}
22-
/>
20+
<fieldset>
21+
<legend>Component</legend>
22+
<input
23+
value_prop={count.value}
24+
onInput={(e) => (count.value = e.target.value)}
25+
/>
2326
24-
<Count value={count.value} />
25-
<Count1 value={count.value} />
26-
<Count2 value={count.value} />
27+
<Count value={count.value} />
28+
<Count1 value={count.value} />
29+
<Count2 value={count.value} />
30+
</fieldset>
31+
32+
<fieldset>
33+
<legend>v-if</legend>
34+
<If></If>
35+
</fieldset>
2736
</>
2837
)
2938
},

playground/if.vue

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<script lang="tsx">
2+
import { defineComponent, ref } from 'vue'
3+
4+
export default defineComponent({
5+
setup() {
6+
const count = ref(1)
7+
8+
const Foo = () => <div style="color: red">2</div>
9+
10+
return (
11+
<div>
12+
<div>
13+
{count.value === 1 ? (
14+
<div>{1}</div>
15+
) : count.value === 2 ? (
16+
<Foo />
17+
) : (
18+
count.value >= 3 && <div>lg 3</div>
19+
)}
20+
</div>
21+
22+
<button onClick={() => count.value++}>+</button>
23+
<button onClick={() => count.value--}>-</button>
24+
</div>
25+
)
26+
},
27+
})
28+
</script>

playground/main.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { createVaporApp } from 'vue/vapor'
22

3-
const modules = import.meta.glob<any>('./**/*.(vue|js)')
4-
const mod = (modules[`.${location.pathname}`] || modules['./App.vue'])()
3+
const modules = import.meta.glob<any>('./*.(vue|js)')
4+
const mod = (modules[`.${location.pathname}.vue`] || modules['./App.vue'])()
55

66
mod.then(({ default: mod }) => {
77
const app = createVaporApp(mod)

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/core/compiler/transforms/transformText.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
isConstantExpression,
1111
resolveExpression,
1212
} from '../utils'
13+
import { processConditionalExpression, processLogicalExpression } from './vIf'
1314
import type {
1415
JSXElement,
1516
JSXExpressionContainer,
@@ -41,7 +42,13 @@ export const transformText: NodeTransform = (node, context) => {
4142
context as TransformContext<JSXElement>,
4243
)
4344
} else if (node.type === 'JSXExpressionContainer') {
44-
processTextLike(context as TransformContext<JSXExpressionContainer>)
45+
if (node.expression.type === 'ConditionalExpression') {
46+
return processConditionalExpression(node.expression, context)
47+
} else if (node.expression.type === 'LogicalExpression') {
48+
return processLogicalExpression(node.expression, context)
49+
} else {
50+
processTextLike(context as TransformContext<JSXExpressionContainer>)
51+
}
4552
} else if (node.type === 'JSXText') {
4653
context.template += node.value
4754
}
@@ -99,5 +106,12 @@ function isAllTextLike(children: Node[]): children is TextLike[] {
99106
}
100107

101108
function isTextLike(node: Node): node is TextLike {
102-
return node.type === 'JSXExpressionContainer' || node.type === 'JSXText'
109+
return (
110+
(node.type === 'JSXExpressionContainer' &&
111+
!(
112+
node.expression.type === 'ConditionalExpression' ||
113+
node.expression.type === 'LogicalExpression'
114+
)) ||
115+
node.type === 'JSXText'
116+
)
103117
}

0 commit comments

Comments
 (0)