vue.js渲染函数适用于结构不确定、逻辑分支多、动态性强的场景,如菜单树、动态表单等,通过h()函数直接生成vnode,支持递归、运行时配置及复杂插槽处理,但需注意v-model手动绑定、ref解包、vnode不可复用等关键陷阱。

Vue.js 渲染函数适合处理结构不确定、逻辑分支多、动态性强的组件场景,比如菜单树、动态表单、条件嵌套很深的布局等。它不依赖模板编译,而是用 JavaScript 直接生成虚拟节点(VNode),因此能更自然地表达判断、循环、递归和运行时配置驱动的 UI。
何时该用渲染函数替代模板
当组件出现以下情况时,模板会变得笨重或不可维护:
- 层级嵌套不确定(如无限级组织架构树、自定义路由菜单)
- 子组件类型需根据后端配置动态决定(如表单项 type = "input" / "select" / "date-picker")
- 需要在渲染阶段做复杂数据转换或组合(例如合并多个插槽、按权限过滤内容)
- 频繁切换结构且希望避免 v-if/v-else-if 链式冗余
核心写法:h() 函数与参数结构
Vue 3 中使用 h() 创建 VNode,它接收三个参数:
- 标签名或组件:字符串(如 'div')、组件对象(如 MyButton)或返回组件的函数
-
props + 事件 + 指令对象:统一放在第二个参数里,比如
{ class: 'btn', onClick: handler } - 子节点:可以是字符串、VNode 数组、或返回 VNode 的函数(尤其用于插槽)
注意:普通 HTML 标签的子节点不能直接传对象,否则渲染为空;而组件的子节点可传插槽对象(this.$slots.default 或 slots.default())。
处理多分支逻辑的常见模式
把分支逻辑提前收束为变量,再统一传入 h(),避免在 return 中堆砌条件表达式:
- 用 if/else 或 switch 明确区分结构,返回不同 h() 调用
- 对列表类结构,用 map + h() 构建子节点数组,key 必须显式设置
- 递归渲染(如 Tree)时,确保每次调用 h() 都创建新 VNode,避免复用同一对象
- 涉及插槽分发时,用
slots.xxx?.()判断是否存在,再决定是否渲染对应区域
必须避开的坑
几个容易导致白屏或响应失效的关键点:
-
v-model 不自动生效:需手动绑定
modelValueprop 和监听onUpdate:modelValue事件 -
ref 数组不会自动解包:若传
ref([1,2,3])给子组件,它收到的是 Ref 对象而非数组,需用ref.value访问 - VNode 对象不可复用:同一个 h() 返回结果不能多次出现在渲染结果中,否则 Vue 会跳过更新
-
插槽函数必须执行:
slots.header是函数,要写成slots.header()才能取到内容
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










