Vue 列表渲染设计决策表(v-for source)
2026年1月22日 13:40
使用场景:
- v-for
- computed → v-for
一、v-for 数据源设计(最核心)
| 问题 | 必须满足 | 正确做法 | 错误做法 | 后果 |
|---|---|---|---|---|
| v-for 的 source 初始值是什么? | 必须可遍历 |
[] / {} / Map()
|
undefined / null / false |
列表语义无法建立 |
| source 的类型是否稳定? | 类型不可跃迁 | [] → [...] |
undefined → [] |
diff 通道缺失 |
| 是否依赖 ?. 比如 v-for = listItem in object?.list | object?.list不能是undefined | 初始值:object=reactive({list:[]}) | 初始值:object=ref(undefined) | 列表语义无法建立 |
二、computed + v-for 决策
| 场景 | 推荐 | 不推荐 | 原因 |
|---|---|---|---|
| computed 作为 v-for source | 返回 []
|
返回 undefined
|
undefind会导致未建立列表语义结构 |
| computed 内部判空 | ?. ?? [] |
if (!x) return |
避免短路,短路会导致v-for source为undefined |
| computed 首次执行 | 访问完整结构 | return {list:[]}这样的预定义稳定结构 | v-for source只会在首次建立列表语义结构,即使source值变化了,也不会再重新建立语义结构 |
| v-for 绑定 | computedList |
computed?.list |
v-for source不能依赖?.,因为可能返回undefined,会导致未定义列表结构语义 |
三、看到v-for检查设计列表
-
v-for 的 source 第一次 render 是不是数组 / 对象?
-
是否存在
undefined → array的路径? -
是否用了
?.直接喂给 v-for? -
computed 是否可能 return 非遍历值?
四、可以反复使用的代码模版
const state = reactive({
list: [],
loading: true
})
onMounted(async () => {
state.list = await fetchList()
state.loading = false
})
<template>
<div v-if="state.loading">loading...</div>
<div v-else>
<div v-for="item in state.list" :key="item.id" />
</div>
</template>
五、关于v-for的统一心智模型
你可以把 Vue 渲染分成三层:
① 编译期(决定结构)
② 首次 render(建立语义)
③ diff 更新(只做比较)
v-for 的“可遍历语义”只在第 ② 步建立一次
如果你在第 ② 步给了:
- undefined
- null
- false
👉 后面改不回来了,即使v-for source变了也不会重新建立
结果:列表一定始终渲染不出来
编译期报错的后果
如果在编译期v-for source = souceObject.property,而且source初始值为null,那么必然报错Can not read property of null (reading property),编译期报错会导致白屏