Vue 能监听数组的情况
Vue 监听数组和对象的变化(vue2.x)
vue 实际上可以监听数组变化,比如:
直接 = 赋值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | data () { return { watchArr: [], }; }, watch: { watchArr (newVal) { console.log( '监听:' + newVal); } }, created () { setTimeout(() => { this .watchArr = [1, 2, 3]; }, 1000); }, |
再如使用 splice(0, 2, 3) 从数组下标 0 删除两个元素,并在下标 0 插入一个元素 3:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | data () { return { watchArr: [1, 2, 3], }; }, watch: { watchArr (newVal) { console.log( '监听:' + newVal); } }, created () { setTimeout(() => { this .watchArr.splice(0, 2, 3); }, 1000); }, |
push、unshift、pop 数组也能够监听到
Vue 无法监听数组变化
但是,数组在下面两种情况无法监听:
利用索引直接设置一个数组项时,例如:arr[indexOfItem] = newValue;
修改数组的长度时,例如:arr.length = newLength;
举例无法监听数组变化的情况
利用索引直接修改数组值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | data () { return { watchArr: [{ name: 'krry' , }], }; }, watch: { watchArr (newVal) { console.log( '监听:' + newVal); } }, created () { setTimeout(() => { this .watchArr[0].name = 'xiaoyue' ; }, 1000); }, |
修改数组的长度
长度大于原数组就将后续元素设置为 undefined
长度小于原数组就将多余元素截掉
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | data () { return { watchArr: [{ name: 'krry' , }], }; }, watch: { watchArr (newVal) { console.log( '监听:' + newVal); } }, created () { setTimeout(() => { this .watchArr.length = 5; }, 1000); }, |
上面的 watchArr 变成
![](https://img-blog.csdnimg.cn/img_convert/ffea1a7124f392ed9524d4c8551671b7.png)
Vue 无法监听数组变化的解决方案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | this .$set(arr, index, newVal); data () { return { watchArr: [{ name: 'krry' , }], }; }, watch: { watchArr (newVal) { console.log( '监听:' + newVal); } }, created () { setTimeout(() => { this .$set( this .watchArr, 0, {name: 'xiaoyue' }); }, 1000); }, |
使用数组 splice 方法可以监听,例子上面有
使用临时变量直接赋值的方式,原理与直接赋值数组一样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | data () { return { watchArr: [{ name: 'krry' , }], }; }, watch: { watchArr (newVal) { console.log( '监听:' + newVal); } }, created () { setTimeout(() => { let temp = [... this .watchArr]; temp[0] = { name: 'xiaoyue' , }; this .watchArr = temp; }, 1000); }, |
Vue 监听对象
Vue 可以监听直接赋值的对象
this.watchObj = {name: 'popo'};
但是 Vue 不能 直接 监听对象属性的添加、修改、删除
Vue 设置监听对象
使用this.$set(object, key, value)、this.$delete(object, key)
使用深度监听 deep: true,只能监听原有属性的变化,不能监听新增、删除的属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | mounted () { // 这里使用深度监听 blog 对象的属性变化,会触发 getCatalog 方法 this .$watch( 'blog' , this .getCatalog, { deep: true // immediate: true // 是否第一次触发 }); }, watch: { obj: { // 这里深度监听变化,直接触发下面方法 handler(curVal, oldVal) { // TODO }, deep: true , immediate: true // 是否第一次触发 } } |
使用this.$set(obj, key, val)来新增属性,this.$delete(object, key)来删除属性
无法使用 this.$set 监听修改原有属性;可以使用深度监听 deep: true,可以直接以 obj.key 的方法来设置原有属性
1 2 3 4 | this .$set( this .watchObj, 'age' , 124); this .$ delete ( this .watchObj, 'age' ) delete this .watchObj[‘name'] //(Vue 无法监听 delete 关键字来删除对象属性) |
使用 Object.assign 方法,直接赋值的原理监听(最推荐的方法)
1 2 3 4 | this .watchObj = Object.assign({}, this .watchObj, { name: 'xiaoyue' , age: 15, }); |
直接 watch obj.key 监听某个值的变化
1 2 3 4 5 | watch: { 'obj.name' (curVal, oldVal) { // TODO } } |