vue3使用jsx语法详解
虽然最早是由 React 引入,但实际上 JSX 语法并没有定义运行时语义,并且能被编译成各种不同的输出形式。如果你之前使用过 JSX 语法,那么请注意 Vue 的 JSX 转换方式与 React 中 JSX 的转换方式不同,因此你不能在 Vue 应用中使用 React 的 JSX 转换。与 React JSX 语法的一些明显区别包括:
- 可以使用 HTML attributes 比如
class和for作为 props - 不需要使用className或htmlFor。 - 传递子元素给组件 (比如 slots) 的方式不同。
添加的配置
1️⃣ tsconfig
{
"compilerOptions": {
"jsx": "preserve",
"jsxImportSource": "vue"
}
}
2️⃣ vite.config.ts
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
export default {
plugins: [vue(), vueJsx()]
}
代码演示
在 vue文件 中
<script setup lang="tsx">
import { computed, defineComponent, ref } from 'vue'
const count = ref(0)
// 1. 定义一个 JSX 片段或小组件
const RenderHeader = () => (
<header>
<h2>这是 JSX 渲染的标题</h2>
<p>当前计数: {count.value}</p>
</header>
)
// 2. 这是一个返回 VNode 的计算属性。搭配 component 使用
const renderContent = computed(() => {
return count.value > 5 ? (
<span>已达到上限</span>
) : (
<button onClick={() => count.value++}>增加</button>
)
})
// 3. 普通组件, setup返回一个渲染函数
const Bbb = defineComponent({
name: 'Bbb',
setup() {
return () => <div>11111</div>
},
})
</script>
<template>
<RenderHeader />
<component :is="renderContent" />
<Bbb />
</template>
注意:
lang的值是 tsx
在 tsx文件 中
// 函数式组件
export default () => {
return <div class={styles.name}>hello world</div>
}
export const Aaa = defineComponent({
setup() {
const t = ref(Date.now())
// 返回渲染函数
return () => <div>aaa {t.value}</div>
},
})
样式方案选型
使用 JSX/TSX,CSS Modules 或 Tailwind CSS 是更好的搭档。Scoped CSS 是专为 Template 设计的。
在 vue文件 中,使用 CSS Modules
<style module>
.header {
color: blue;
}
.content {
color: green;
}
.bbb {
color: red;
}
</style>
eslint
要在 vue文件 中使用tsx,应添加 configureVueProject 的配置
configureVueProject({ scriptLangs: ['ts', 'tsx'] })
export default defineConfigWithVueTs(
{
name: 'app/files-to-lint',
files: ['**/*.{ts,mts,tsx,vue}'],
},
globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']),
pluginVue.configs['flat/essential'],
vueTsConfigs.recommended,
skipFormatting,
)