一、响应式对象和响应式数组
在Vue3中,响应式对象和响应式数组都是采用函数式API解决了数据的响应式问题。Vue3的reactive()函数可以对对象进行响应式化处理,而reactive()函数内部会判断传入的对象是否为数组类型,如果是,则会调用ref()函数将数组转换为响应式数组,这样在数组对象进行增加、修改、删除操作后,即可自动触发DOM的更新。
import { reactive } from 'vue'
const state = reactive({
arr: [1, 2, 3],
obj: {
name: 'Jack',
age: '18'
}
})
上述代码中的state.arr数组使用了Vue3的reactive()函数进行响应式化处理,接下来可以在Vue组件中进行引用,即可达到监听状态改变的目的。
二、响应式数组的常用API
1、push()方法
通过调用数组的push()方法,在末尾添加一个或多个元素,并返回新的数组长度。这时候,因为是使用了Vue3的响应式数组,DOM会自动更新。
state.arr.push(4)
// state.arr变成[1, 2, 3, 4]
2、pop()方法
在数组末尾移除最后一个元素,并返回该元素。同样,因为使用了响应式数组,DOM会自动更新。
state.arr.pop()
// state.arr变成[1, 2]
3、shift()方法
在数组开头移除第一个元素,并返回该元素。同样,因为使用了响应式数组,DOM会自动更新。
state.arr.shift()
// state.arr变成[2, 3]
4、unshift()方法
在数组开头添加一个或多个元素,并返回新的数组长度。同样,因为使用了响应式数组,DOM会自动更新。
state.arr.unshift(0)
// state.arr变成[0, 1, 2, 3]
5、splice()方法
在指定位置删除多少个元素并添加新的元素。同样,因为使用了响应式数组,DOM会自动更新。
state.arr.splice(1, 2, 5, 6)
// state.arr变成[1, 5, 6]
6、slice()方法
返回一个新数组,包含从开始到结束(不包括结束)的所有元素。slice()方法不会更改原始数组,只是返回一个新的数组,需要注意的是,slice()方法的第一个参数是开始的索引,第二个参数是结束的索引。同样,因为使用了响应式数组,DOM会自动更新。
const newArr = state.arr.slice(1, 2)
// newArr是[2],state.arr还是[1, 2, 3]
三、响应式数组的高级操作
1、computed属性
computed属性可以将一个普通的属性值转换成一个计算属性,只要依赖的数据发生变化,它就会自动更新。此外,computed属性返回的值要么是基本类型的值,要么是一个响应式对象或者数组。在本例中,通过computed属性获取响应式数组的长度,只要数组发生变化,computed属性值就会自动更新。
import { computed } from 'vue'
const length = computed(() => state.arr.length)
2、watch()方法
watch()方法可以监听数组对象中某个属性的变化,并做出相应的操作,可以为变化的属性设置一个回调函数。在本例中,当响应式数组发生变化时便会执行该回调函数,并传递修改后的数组和修改前的数组。
watch(
() => state.arr,
(newVal, oldVal) => {
// do something
}
)
四、响应式数组的限制
Vue3中的响应式数组虽然操作方便,易于控制,但是仍存在几个需要注意的点,其中最主要的是:
1、直接更改数组的某一项不会触发视图更新
通过索引值直接修改数组中的某一项时,并不能够触发视图的更新,需要手动调用splice()方法来实现更新。这是由于Vue3不能侦测到通过索引值进行修改的操作,需要手动进行触发。
在Vue2的版本中,使用Vue.set()或者this.$set()的方法可以实现对数组的某一项进行值的更改,但在Vue3中这两个方法的使用已经被移除,应该使用splice()方法来替代。
2、因为限制更新性能问题,无法观测数组索引的变化
由于Vue3为了优化性能,不会对数组中的索引进行观察,因此新增或删除数组元素时才会触发视图更新。如果想要直接更新某一个索引值,需要手动调用splice()方法。
综上所述,响应式数组操作时需要注意索引直接修改没有触发视图更新、新增删除元素才能触发视图更新等问题,但是这些问题都可以通过手动调用方法进行监控、更新解决,从而达到需要的效果。