Vue基础_v-for更新机制

1,119 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第四天, 点击查看活动详情

Vue基础_v-for更新机制

当 Vue 正在更新使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。这个类似 Vue 1.x 的 track-by="$index"

v-for更新监测

可以这样简单的理解

  • 数组变更方法(修改了原数组), 就会导致v-for更新, 页面更新
  • 数组非变更方法(不修改原数组), 返回新数组, 就不会导致v-for更新, 可采用覆盖数组或this.$set()
<template>
  <div>
    <ul>
      <li v-for="(val, index) in arr" :key="index">
        {{ val }}
      </li>
    </ul>
    <button @click="revBtn">数组翻转</button>
    <button @click="sliceBtn">截取前3个</button>
    <button @click="updateBtn">更新第一个元素值</button>
  </div>
</template>

<script>
export default {
  data(){
    return {
      arr: [5, 3, 9, 2, 1]
    }
  },
  methods: {
    revBtn(){
      // 1. 数组翻转可以让v-for更新
      this.arr.reverse()
    },
    sliceBtn(){
      // 2. 数组slice方法不会造成v-for更新
      // slice不会改变原始数组
      // this.arr.slice(0, 3)

      // 解决v-for更新 - 覆盖原始数组
      let newArr = this.arr.slice(0, 3)
      this.arr = newArr
    },
    updateBtn(){
      // 3. 更新某个值的时候, v-for是监测不到的
      // this.arr[0] = 1000;

      // 解决-this.$set()
      // 参数1: 更新目标结构
      // 参数2: 更新位置
      // 参数3: 更新值
      this.$set(this.arr, 0, 1000)
    }
  }
}
</script>

<style>

</style>

这些方法会触发数组改变, v-for会监测到并更新页面

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

这些方法不会触发v-for更新

  • slice()
  • filter()
  • concat()

注意: vue不能监测到数组里赋值的动作而更新, 如果需要请使用Vue.set() 或者this.$set(), 或者覆盖整个数组 小结

  • 哪些数组方法会导致v-for更新页面?
    • 可以改变原数组的方法
  • 有的数组方法不导致v-for更新页面, 如何处理?
    • 拿返回的新数组, 直接替换旧数组
    • this.$set()方法更新某个值

v-for就地更新

v-for 的默认行为会尝试原地修改元素而不是移动它们。 从变化节点往后, 会依次变化

这种 DOM对比方式, 可以提高性能 - 但是还不够高

准备代码

<template>
  <div>
    <ul>
      <li v-for="(val, ind) in arr" :key="ind">
        {{ val }}
      </li>
    </ul>
    <button @click="btn">下标1位置插入新来的</button>
  </div>
</template>

<script>
export default {
  data(){
    return {
      arr: ['老大', "老二", '老三']
    }
  },
  methods: {
    btn(){
      this.arr.splice(1, 0, '新来的')
    }
  }
}
</script>

<style>

</style>

image.png 小结

  • v-for更新时, 是如何操作DOM的?
    • 尝试复用标签就地更新内容