数组响应式
1. 基本理解
arr[i] = xxx和arr.length = len:这两种方式都不会立刻触发响应式
push pop shift unshift splice sort revcerse 或者直接给数组赋值等都会触发响应式
concat、filters、slice等等不对数组本身造成变化的都不会出发响应式
concat会返回新数组,不对原有数组操作
// 示例1:
items: [
{ name: "a", age: 10 },
{ name: "b", age: 5 }
]
vm.items[0].age =20 // 会触发渲染
items: [1, 2] vm.items[0]=99 // 不会触发渲染,但是值在内存中,如果有其他的渲染,那么这个内存的值会被一起渲染出去
vm.items.push(6) // 99 2 6
2. 通过set实现数组下标响应式
// 方式1:
vm.$set(vm.items, indexOfItem, newValue)
//vm.$set(数组名字, 改变的索引位置, 需要更改的值)
//this.$set(arr,1,'我想要不要被改变')
// 方式2:
Vue.set(vm.items, indexOfItem, newValue)
//Vue.set(数组名字, 改变的索引位置, 需要更改的值)
// Vue.set(arr,1,'我想被改变')
对象响应式
1. 基本理解
Vue不能检测对象属性的添加、删除(仅此而已,可直接对该对象重新赋值、修改该对象或内层对象的属性)
也就是说已经有了一个对象,如果我们手动给对象增加属性,或者删除属性,那么vue检测不到变化。
// 示例1:
items: {
name: "xiaomei",
age: 18,
habby: {}
}
vm.items.habby.a = 'AA' // 不会触发重渲染, 但是值在内存中
vm.items.age = 20 // 触发重渲染,并且将habby.a在内存中的值也渲染了
// 删除age或者增加新属性都不会触发冲渲染
2. 通过set实现对象响应式
方法一:Vue.set(对象, 对象属性, 属性值)
方法二:this.$set(对象, 对象属性, 属性值)
eg:this.$set(item, 'taskList', [1,2,3])
item: {
taskList: [1,2,3]
}
Vue.delete()&this.$delete()
一般我们删除对象某个属性,使用delete obj.xx,这种删除操作不会触发响应式,但是如果我们需要删除操作是响应式的,可以使用
Vue.delete(obj, 'key')
或者
this.$delete(obj, 'key')
遗漏点总结
<template>
<div>
<div>a: {{ a }}</div>
<div @click="clickBtn">点我</div>
<div>a: {{ a }}</div>
</div>
</template>
<script>
export default {
data () {
return {
a: {
b: 'bbbbb',
c: {
d: 'ddddd'
}
}
}
},
methods: {
clickBtn () {
console.log('this.a前====>', this.a);
// 对a整体赋值替换之后,a中的原有属性bcd仍然是响应式的,新加的e仍然是响应式的,因为
// vue在data进行set赋值的时候,还会通过observe方法去判断这个新值是否是对象,而且
// 是否已经有响应式初始化。如果没有,重新对其进行响应式初始化。这里e就是被重新响应式初始化的
this.a = {
b: 'xxxxx',
c: {
d: 'tttttt'
},
e: 'eeeeeee'
}
this.a.b = 'uuuuu'
// 这种方式的新增对象属性h是不具有响应式的
this.a.h = 'hhhhhh'
// 对象实例的f属性并不属于data中,也不具有响应式;如果需要f成为响应式,除了$set之外,还必须将f变成data中的一个属性(挂载到data中的对象或者数组中)
this.f = 'ffffff'
console.log('this.a后====>', this.a);
console.log('this前', this);
// 这种方式给data中的a新增的g属性是具有响应式的。
this.$set(this.a, 'g', 'gggggg')
console.log('this后', this);
}
}
}
</script>
<style>
</style>
-
已经在data中对象/数组,如果想添加响应式属性时,可以采用$set的方式;如果这个变量本身就不在data中,那么是没有办法变成data中的响应式变量的。
-
data中的对象/数组进行整体替换的时候,如果替换的新对象或者数组中多了属性,那么这个多的属性也是响应式的;因为vue在data进行set赋值的时候,还会通过observe方法去判断这个新值是否是对象,而且是否已经有响应式初始化。如果没有,重新对其进行响应式初始化
-
可以在控制台通过某个属性是否有set和get判断这个属性是否是响应式
写在后面
可以结合博主的另外一篇文章看,印象会更深刻