Vue渲染器静默跳过null、undefined、false和空字符串'',不生成DOM也不报错;0、[]、{}等falsy值则正常渲染。

Vue 渲染器对 null 和 undefined 的处理是静默跳过,不生成 DOM,也不抛错——这是框架层内置的“安全屏障”,而非运行时兜底逻辑。
哪些值会被跳过渲染?
在模板插值、v-if、v-for、组件 render 函数返回值等上下文中,以下四个值被统一识别为“空”并跳过:
nullundefined-
false(注意:仅字面量false,不是所有 falsy 值) - 空字符串
''
而 0、[]、{}、NaN 等虽为 falsy 或“空结构”,但不会被跳过,会按类型正常参与渲染(如 {{ 0 }} 显示 “0”,{{ [] }} 显示空数组字符串 "")。
v-if 和插值中空值行为差异
同一值在不同上下文表现不同,本质是语义不同:
-
v-if="val"只做布尔强制转换(falsy → 不渲染),所以0、''、null都不渲染 -
{{ val }}是内容插入,有独立规则:
→{{ null }}/{{ undefined }}→ 渲染为空白文本节点(DOM 中存在但不可见)
→{{ false }}→ 渲染为字符串"false"(因为String(false) === 'false')
render 函数与 Composition API 中的过滤逻辑
在 setup() 返回的 render() 函数中,返回值若为数组,渲染器会自动剔除无效项:
-
return () => null→ 整个组件无任何输出 -
return () => [null, h('div', 'hello')]→ 自动过滤null,只渲染<div>hello</div> - 同理,
undefined和false也会被剔除;但0、''、[]保留并渲染
底层保护的关键点
这种跳过不是靠 try-catch 实现的,而是渲染器在 vnode 构建阶段就完成的语义判断:
- 模板编译后,插值表达式结果直接进入“内容分支”,
null/undefined被转为createTextVNode('') -
v-if编译为条件分支,其值经toBoolean()判断后决定是否创建子 vnode - 组件返回值(如
render())在 patch 前被 normalizeChildren 处理,执行filterSingleRoot过滤掉无效节点
这层保护让开发者无需为每个插值加 v-if 或 ??,但也要清楚它不解决数据访问异常(如 {{ user.profile.name }} 中 user 为 null 仍会报错)——那是响应式取值阶段的问题,需靠 ?. 或初始化兜底来应对。

















