首页 > 试题广场 >

在一个性能敏感的 Vue 3 应用中,你有一个组件渲染一个大

[单选题]
在一个性能敏感的 Vue 3 应用中,你有一个组件渲染一个大数据列表。该组件接收多个 props,但你希望列表的 DOM 更新只在 `items` 这个 prop 的引用地址发生变化时才执行,忽略其他 prop (如 `title`, `theme`) 的变化,以避免不必要的渲染。哪种方式是最高效且最符合该场景的优化策略?
  • 在组件根元素上使用 `v-once`,并在 `items` 变化时手动强制更新组件。
  • 使用 `watch` 监听 `items` prop,当它变化时通过修改一个本地的 `ref` 来触发模板更新。
  • 在渲染列表的循环外层容器上使用 `v-memo="[items]"`。
  • 使用 `computed` 属性返回 `items`,并在模板中渲染这个 `computed` 属性。
  v-memo 是 Vue 3.2+ 引入的内置指令,用于有条件地跳过子树的更新,是一种手动的渲染优化手段。
  
核心原理:
  接收一个依赖数组,只有数组中的值发生变化时,才重新渲染该元素及其子树。依赖未变化时,直接复用上次的 VNode,跳过 diff 和重新渲染。
  <div v-memo="[a, b]">
    <!-- 只有 a 或 b 变化时才重新渲染 -->
  </div>

  典型用法:

  1. 优化大列表(最主要的使用场景)
  与 v-for 配合,避免列表中未变化的项重新渲染:
  <ul>
    <li
      v-for="item in list"
      :key="item.id"
      v-memo="[item.selected, item.name]"
    >
      <span>{{ item.name }}</span>
      <input v-model="item.value" />
      <span :class="{ active: item.selected }">选中</span>
    </li>
  </ul>
  ▎ 每次只有 selected 或 name 变化的 <li> 才会重新渲染,其余直接跳过。

  2. 配合 v-for 的注意点
  v-memo 必须和 :key 写在同一元素上:
  <!-- 正确 -->
  <div v-for="item in list" :key="item.id" v-memo="[item.id, item.done]">

  <!-- 错误:key 和 memo 分离 -->
  <template v-for="item in list" :key="item.id">
    <div v-memo="[item.done]">  <!-- 不要这样写 -->

  3. 传空数组 = 永不更新(相当于 v-once)
  <div v-memo="[]">
    <!-- 只渲染一次,之后永远不更新 -->
    {{ staticContent }}
  </div>
 
使用限制:
  - 不要滥用:只在确认有性能问题时使用,过度使用会让代码难以理解
  - 依赖必须完整:遗漏依赖项会导致视图不更新的 bug(类似 useEffect 的依赖陷阱)
  - 不适合小列表:列表项少时,memo 的比较开销可能比重新渲染还大
  - Vue 3.2+ 专属:Vue 2 不支持

 总结:
  v-memo 的核心价值在于超大列表的性能优化(数百到数千项),普通场景下 Vue 的响应式系统已经足够高效,不需要手动干预。


发表于 今天 15:29:22 回复(0)