render函数是Vue提供的用于替代模板的底层API,适用于动态生成复杂组件、精细控制VNode、高阶封装、TypeScript强类型推导及性能关键路径手动优化等场景。

当模板语法“写不动”或“不够快”的时候,就是该用 render 函数的时候。
需要动态生成复杂结构的组件
比如表单生成器、可视化配置面板、低代码平台的画布渲染——字段类型、嵌套层级、校验规则都来自后端 JSON。模板里堆 v-if/v-for 嵌套容易失控,而 render 函数可以用纯 JavaScript 遍历 schema,递归调用 h() 创建对应节点,逻辑更清晰、分支更可控。
- 根据字段 type 渲染 input / select / date-picker 等不同组件
- 动态插入 wrapper 容器或校验提示节点
- 运行时决定是否包裹
Teleport或添加v-memo优化标记
需要精细控制虚拟 DOM 节点细节
模板对 props、attrs、slots、ref、key 的传递是隐式的;render 函数则把所有参数显式暴露在 h(tag, props, children) 的三个入参中。适合做高阶封装,比如:
- 自定义指令无法覆盖的 DOM 行为(如聚焦后自动选择文本)
- 给子组件注入上下文但不污染其原始 props
- 手动合并多个具名插槽、过滤空 slot、添加默认 fallback 内容
构建高复用、强类型的可编程组件
在 TypeScript 项目中,render 函数配合接口约束,能实现比模板更严格的类型推导。例如一个通用表格组件:
- 列配置数组的每一项可声明
renderCell: (row: T) => VNode - 排序/分页状态通过函数参数传入,避免依赖 data 响应式对象
- 支持返回 Fragment、Portal、Suspense 等非根节点结构,模板无法直接表达
性能关键路径需手动干预
Vue 模板编译器虽做了很多优化,但某些场景它“不敢动”。比如:
- 大量静态节点 + 少量动态节点混合时,手动用
v-memo或h(Fragment, [...])更精准 - 避免响应式追踪开销:用
shallowRef存储 vnode 并在 render 中直接返回,跳过 diff - 服务端渲染中预设 hydration 标记,或客户端接管前做轻量 DOM 预处理
不复杂但容易忽略:render 函数不是替代模板的“高级模式”,而是 Vue 给你留的一扇后门——只在真正需要 JavaScript 全能力的时候才推开它。

















