面试题答案
一键面试Vue检测数组变更的原理
Vue 不能检测以下数组的变动:
- 当你利用索引直接设置一个数组项时,例如:
vm.items[indexOfItem] = newValue
- 当你修改数组的长度时,例如:
vm.items.length = newLength
Vue 内部通过覆盖数组的原型方法,使用了被称为“变异方法”来检测数组变化。Vue 将 Array.prototype
上的 7 个变异方法(push
、pop
、shift
、unshift
、splice
、sort
、reverse
)进行了包裹,当调用这些变异方法时,不仅会改变数组本身,还会触发视图更新。
确保数组变化能触发视图更新的方法
- 使用变异方法
push
:向数组的末尾添加一个或多个元素,并返回新的长度。例如:
let arr = [1, 2, 3]; arr.push(4);
pop
:删除并返回数组的最后一个元素。例如:
let arr = [1, 2, 3]; arr.pop();
shift
:删除并返回数组的第一个元素。例如:
let arr = [1, 2, 3]; arr.shift();
unshift
:向数组的开头添加一个或多个元素,并返回新的长度。例如:
let arr = [1, 2, 3]; arr.unshift(0);
splice
:用于插入、删除或替换数组的元素。例如,删除元素:
let arr = [1, 2, 3]; arr.splice(1, 1); // 从索引1开始删除1个元素
sort
:对数组的元素进行排序。例如:
let arr = [3, 1, 2]; arr.sort();
reverse
:颠倒数组中元素的顺序。例如:
let arr = [1, 2, 3]; arr.reverse();
- 使用 Vue.set 或 this.$set
- 当需要通过索引直接设置一个数组项时,可以使用
Vue.set
(在全局引入 Vue 时) 或this.$set
(在组件内部)。例如:
在组件内:import Vue from 'vue'; let arr = [1, 2, 3]; Vue.set(arr, 1, 5); // 将索引为1的元素设置为5
export default { data() { return { arr: [1, 2, 3] }; }, methods: { updateArray() { this.$set(this.arr, 1, 5); } } };
- 当需要通过索引直接设置一个数组项时,可以使用
- 替换数组
- 可以通过创建一个新的数组来替换原来的数组,这样也能触发视图更新。例如:
在 Vue 组件中:let arr = [1, 2, 3]; arr = arr.filter(item => item!== 2);
<template> <div> <ul> <li v - for="(item, index) in arr" :key="index">{{item}}</li> </ul> <button @click="updateArray">Update Array</button> </div> </template> <script> export default { data() { return { arr: [1, 2, 3] }; }, methods: { updateArray() { this.arr = this.arr.filter(item => item!== 2); } } }; </script>