Vue 渲染体系“三件套”(template 模板语法、h 函数和 JSX 语法)

前言

不管你写 template、h() 还是 JSX,最后都会变成 VNode → patch → DOM

一、template 模板语法------ 最常用、最友好

特点:

  • 面向业务开发
  • 声明式
  • 会被编译成 render 函数

1、插值表达式

typescript 复制代码
<div>{{ message }}</div>

数据变化 → 自动更新 DOM

2、指令系统(Vue 模板核心)

指令 作用
v-bind 绑定属性
v-on 绑定事件
v-if / v-else 条件渲染
v-for 列表渲染
v-model 双向绑定
v-slot 插槽
typescript 复制代码
<button @click="add">+1</button>
<img :src="imgUrl" />
<li v-for="item in list" :key="item.id">{{ item.name }}</li>

3、组件 & 插槽

typescript 复制代码
<MyCard title="标题">
  <template #default>
    内容
  </template>
</MyCard>

本质:

  • 模板不会直接操作 DOM,而是被编译成:
typescript 复制代码
render() {
  return h('div', message)
}

4、简单示例

typescript 复制代码
<script setup>
import { ref } from 'vue'

const count = ref(0)
const add = () => count.value++
</script>

<template>
  <div class="box">
    <p>Count: {{ count }}</p>
    <button @click="add">+1</button>
  </div>
</template>

二、h() 函数------ 虚拟 DOM 的直接写法

特点:

  • render 函数的核心
  • 手写虚拟 DOM
  • 所有模板最终都会变成 h()

基本格式:

typescript 复制代码
h(type, props, children)

1、普通元素

typescript 复制代码
h('div', { class: 'box' }, 'Hello')

2、子节点数组

typescript 复制代码
h('ul', null, [
  h('li', null, 'A'),
  h('li', null, 'B')
])

3、事件绑定

typescript 复制代码
h('button', { onClick: this.add }, 'Add')

4、渲染组件

typescript 复制代码
h(MyCard, { title: '标题' }, {
  default: () => h('span', '内容')
})

本质:

  • h() 返回 VNode 对象
typescript 复制代码
{
  type: 'div',
  props: { class: 'box' },
  children: 'Hello'
}

然后进入:

typescript 复制代码
patch(oldVNode, newVNode)

5、简单示例

typescript 复制代码
import { h, ref } from 'vue'

export default {
  setup() {
    const count = ref(0)
    const add = () => count.value++

    return () =>
      h('div', { class: 'box' }, [
        h('p', null, 'Count: ' + count.value),
        h('button', { onClick: add }, '+1')
      ])
  }
}

三、JSX 语法------ 更自由的"类模板语法"

特点:

  • 本质是 h() 的语法糖
  • JS 表达能力更强
  • 适合复杂动态结构

1、JSX 写法

typescript 复制代码
return <div class="box">{msg}</div>

编译后:

typescript 复制代码
h('div', { class: 'box' }, msg)

2、条件渲染

typescript 复制代码
return count > 0
  ? <span>正数</span>
  : <span>负数</span>

3、列表渲染

typescript 复制代码
return (
  <ul>
    {list.map(item => <li key={item.id}>{item.name}</li>)}
  </ul>
)

4、插槽

typescript 复制代码
return <MyCard v-slots={{
  default: () => <span>内容</span>
}} />

5、简单示例

typescript 复制代码
import { ref } from 'vue'

export default {
  setup() {
    const count = ref(0)
    const add = () => count.value++

    return () => (
      <div class="box">
        <p>Count: {count.value}</p>
        <button onClick={add}>+1</button>
      </div>
    )
  }
}

四、三者关系总结

typescript 复制代码
Template  → 编译 → render 函数 → h()
JSX       → 编译 → h()
h()       → 生成 VNode
VNode     → patch → 真实 DOM

它们只是"写法不同",底层渲染机制完全一样。

  • Template 最好写,h() 最底层,JSX 最灵活;
  • 三者最终都会变成 h() 创建的 VNode,再由 Vue 的 patch 机制更新真实 DOM。
相关推荐
xkxnq6 小时前
第五阶段:Vue3核心深度深挖(第74天)(Vue3计算属性进阶)
前端·javascript·vue.js
Hilaku6 小时前
不要在简历上写精通 Vue3?来自面试官的真实劝退
前端·javascript·vue.js
竟未曾年少轻狂7 小时前
Vue3 生命周期钩子
前端·javascript·vue.js·前端框架·生命周期
TT哇7 小时前
【实习】数字营销系统 银行经理端(interact_bank)前端 Vue 移动端页面的 UI 重构与优化
java·前端·vue.js·ui
用户982450514188 小时前
vue3响应式解构注意
vue.js
不会敲代码18 小时前
🚀 从DOM操作到Vue3:一个Todo应用的思维革命
vue.js
未来龙皇小蓝9 小时前
RBAC前端架构-02:集成Vue Router、Vuex和Axios实现基本认证实现
前端·vue.js·架构
晓得迷路了9 小时前
栗子前端技术周刊第 116 期 - 2025 JS 状态调查结果、Babel 7.29.0、Vue Router 5...
前端·javascript·vue.js
淡忘_cx9 小时前
使用Jenkins自动化部署vue项目(2.528.2版本)
vue.js·自动化·jenkins