阅读视图

发现新文章,点击刷新页面。

Vue 列表渲染设计决策表(v-for source)

使用场景:

  • 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),编译期报错会导致白屏

❌