v-for 的“就地更新”策略


highlight: a11y-light

前言

我们平时使用v-for的时候通常都是加一个唯一标识key,因为不加的时候Vue会给我们发出警告。其实我们加上key的操作,就是为了避免它的“就地更新”策略。我们来看一下官网对“就地更新”的解释:

当 Vue 正在更新使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。这个类似 Vue 1.x 的 track-by="$index"
这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出
建议尽可能在使用 v-for 时提供 key attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。

没有key 使用默认的“就地更新”策略

<template>
  <ul>
    <li v-for="(item, index) in list">
      <input type="text" :placeholder="item.value"> <button @click="del(index)">删除</button>
    </li>
  </ul>
</template>

<script>
export default {
  name: 'test',
  data () {
    return {
      list: [
        { value: 'test1', id: 1 },
        { value: 'test2', id: 2 },
        { value: 'test3', id: 3 },
        { value: 'test4', id: 4 },
        { value: 'test5', id: 5 }
      ]
    }
  },
  methods: {
    del (index) {
      this.list.splice(index, 1)
    }
  }
}
</script>
  • 效果如下:

Filmage 2022-11-18_152728-filmage 2.gif

我们只观察左边会发现很奇怪的现象,就是我们明明删除的是第一项,但好像是删除的最后一项;
接着看右边,第一项li标签及其子元素都没有变化,唯一变化的是placeholder属性值,注意看这是在第一个li上直接更新的,也就是复用了第一个li的DOM结构,后边的li标签以此类推,最后删除掉最后一个li元素

我们如何避免“就地更新”策略

给元素加上唯一的key就行了

Filmage 2022-11-18_163729-filmage.gif

这样Vue就会基于key的变化重新排列元素顺序,并且会移除key不存在的元素。 可以简单认为key是给每一个DOM节点一个唯一标识,这样Vue就不会启用就地更新了。
这就印证了官网中的一句话:这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出

结论

使用v-for的时候,默认使用就地更新策略,这会导致一些更新的问题,如何避免呢?那就是乖乖的加上key

© 版权声明
THE END
喜欢就支持一下吧
点赞7 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容