欢迎光临
我们一直在努力

13、告别繁琐template!Vue3 JSX让动态组件开发更丝滑

告别繁琐template!Vue3 JSX让动态组件开发更丝滑

在Vue开发的日常中,你是否也曾被template的固定语法束缚?想实现动态标签渲染却要写一堆v-if?想做高度动态的组件逻辑却被template的语法限制住?

其实Vue3早就为我们准备了更灵活的方案——JSX。它不是React的专属,在Vue3中,JSX能完美弥补template的灵活性短板,让我们在复杂场景下写组件更丝滑。这篇文章就带你从底层原理到实战落地,彻底搞懂Vue3的JSX!

一、先搞懂:为什么需要JSX?(h函数铺垫)

在聊JSX之前,必须先提h函数——因为JSX的本质就是h函数的语法糖。

1. template的局限性

先看一个简单需求:根据传入的数字(1-6),动态渲染h1~h6标签。如果用template实现,只能写一堆冗余的v-if:

<template>
<h1 v-if="level===1">{{ title }}</h1>
<h2 v-if="level===2">{{ title }}</h2>
<h3 v-if="level===3">{{ title }}</h3>
<!– … 还要写h4/h5/h6 –>
</template>

这种写法不仅冗余,而且动态性极差——如果后续要扩展更多动态逻辑,template会变得难以维护。

2. h函数:手写虚拟DOM

Vue3中,template最终会被编译成render函数,而render函数的核心是通过h函数创建虚拟DOM(VNode)。我们可以直接手写h函数,摆脱template的束缚:

新建Heading.jsx(注意后缀是jsx):

import { defineComponent, h } from 'vue'

export default defineComponent({
props: {
level: {
type: Number,
required: true
}
},
setup(props, { slots }) {
// render函数返回h函数的执行结果
return () => h(
'h' + props.level, // 动态拼接标签名
{}, // 属性/Props
slots.default() // 子节点(插槽)
)
}
})

使用时只需要传一个level参数:

<template>
<Heading :level="3">Hello Vue3 JSX</Heading>
</template>

<script setup>
import Heading from './components/Heading.jsx'
</script>

h函数完美解决了动态标签的问题,但问题来了:复杂场景下h函数写起来太繁琐——嵌套组件时要层层嵌套对象,属性也要手动组装,可读性和开发效率都很低。

这时候,JSX就该登场了!

二、JSX核心:h函数的“语法糖”

1. 什么是JSX?

JSX是“在JavaScript中写HTML”的语法扩展,比如:

const element = <h1 id="app">Hello, Geekbang!</h1>

这段代码看起来像HTML,但本质是下面这段代码的语法糖:

const element = createVnode('h1',{id:"app"}, 'Hello, Geekbang!')

而createVnode正是h函数的核心逻辑——所以JSX最终还是会被解析成h函数执行,既保留了JavaScript的动态性,又拥有HTML的直观写法。

2. Vue3中配置JSX(Vite环境)

要在Vue3中用JSX,需要先安装插件并配置:

步骤1:安装依赖

npm install @vitejs/plugin-vue-jsx -D

步骤2:修改vite.config.js

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx';

export default defineConfig({
plugins: [vue(), vueJsx()] // 注册JSX插件
})

3. 用JSX改写h函数示例

回到前面的Heading组件,用JSX改写后,代码更简洁直观:

import { defineComponent } from 'vue'

export default defineComponent({
props: {
level: {
type: Number,
required: true
}
},
setup(props, { slots }) {
const tag = 'h' + props.level
// 直接写JSX,替代繁琐的h函数调用
return () => <tag>{slots.default()}</tag>
}
})

是不是瞬间清爽了?这就是JSX的核心价值——用更直观的语法,实现h函数的动态能力。

三、Vue3 JSX实战语法要点

JSX的本质是JavaScript,所以能兼容所有JS语法,同时也有一些和template的语法差异,这里整理了核心实战要点:

1. 基础语法对比(template → JSX)

功能template写法JSX写法
双向绑定 v-model="title" vModel={title.value}
事件绑定 @click="handleClick" onClick={handleClick}
条件渲染 v-if/v-else 三元表达式/if-else
列表渲染 v-for="item in list" list.map(item => {})

2. 实战示例:用JSX实现待办清单

新建Todo.jsx,实现一个简单的待办清单,感受JSX的灵活性:

import { defineComponent, ref } from 'vue'

export default defineComponent({
setup(props) {
// 响应式数据
let title = ref('')
let todos = ref([
{ title: "学习 Vue3 JSX", done: true },
{ title: "手写h函数", done: false }
]);

// 新增待办
function addTodo() {
if (!title.value) return
todos.value.push({ title: title.value })
title.value = ''
}

// 返回JSX结构
return () => (
<div class="todo-container">
<input
type="text"
vModel={title.value}
placeholder="请输入待办事项"
/>
<button onClick={addTodo}>添加</button>
<ul class="todo-list">
{
// 列表渲染 + 条件判断
todos.value.length
? todos.value.map((todo, index) => (
<li key={index}>{todo.title}</li>
))
: <li>暂无待办事项</li>
}
</ul>
</div>
)
}
})

在Vue文件中引入使用:

<template>
<Todo />
</template>

<script setup>
import Todo from './components/Todo.jsx'
</script>

3. 高级场景:组件库级别的动态逻辑

在组件库开发中(比如Element3),JSX的动态性优势更明显。比如时间轴(Timeline)组件的“倒序渲染”需求:

export const Timeline = (props) => {
const timeline = [
<div class="timeline-item">8.21 开始学习Vue3</div>,
<div class="timeline-item">10.18 掌握JSX用法</div>
]
// 根据props动态反转数组,实现倒序
if (props.reverse) {
timeline.reverse()
}
return <div class="timeline">{timeline}</div>
}

这种“直接操作JS数组实现DOM逻辑”的场景,用template很难优雅实现,而JSX可以轻松搞定。

四、JSX vs Template:该怎么选?

很多同学会纠结:到底该用JSX还是template?核心原则是**“按场景选型”**:

1. Template的优势

  • 编译优化更强:Vue对template做了大量编译期优化(比如静态节点提升、动态节点标记),静态内容会被缓存,Diff算法会跳过静态节点,性能更高;
  • 语法更规范:固定的v-if/v-for等语法,团队协作成本低;
  • 更贴近HTML:适合大部分常规业务场景(比如表单、列表展示)。

2. JSX的优势

  • 动态性极强:支持所有JavaScript语法,适合“标签动态、逻辑复杂”的场景(比如动态标签、组件库开发);
  • 灵活性更高:一个文件可以导出多个组件,无需拆分多个.vue文件;
  • 逻辑内聚:JS逻辑和DOM结构写在一起,适合复杂交互的组件。

3. 选型建议

  • 优先用template:常规业务页面(比如列表、表单、详情页)用template,享受Vue的编译优化;
  • 按需用JSX:动态标签、复杂逻辑组件(比如自定义表单、组件库组件)用JSX,解决template的灵活性不足问题。

五、总结

Vue3的JSX不是“替代template”,而是“补充template”——它让Vue的组件开发能力更完整:

  • h函数是Vue创建虚拟DOM的底层API,解决了template动态性不足的问题,但手写繁琐;
  • JSX是h函数的语法糖,兼具JavaScript的动态性和HTML的直观性;
  • Template适合常规场景,享受编译优化;JSX适合高动态场景,解锁灵活开发;
  • 最后留一个思考题:你在实际项目中,遇到过哪些template难以实现、但用JSX能轻松搞定的场景?欢迎在评论区交流~

    拓展资料

    • Vue3官方文档:渲染函数 & JSX
    • Vue JSX插件文档:@vue/babel-plugin-jsx
    赞(0)
    未经允许不得转载:171主机测评 » 13、告别繁琐template!Vue3 JSX让动态组件开发更丝滑
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址