豁然高

导航

vue响应式原理

深入响应式原理官方文档

https://cn.vuejs.org/v2/guide/reactivity.html

 

总结:

1.对值进行响应式转化会对该值内所有对象的属性都转化为响应式属性,包括作为数组元素值的对象的属性也会被转化为响应式属性。

2.响应式属性只能是对象的属性,而不能是数组元素,响应式属性的属性值发生变化才会触发响应,而元素的元素值发生变化并不会触发响应

 注意:元素的元素值发生变化不会触发响应,比如给该元素重新赋值一个新对象,则不会触发响应,也不会对新对象进行响应式转化

            但是作为元素值的对象的属性值发生变化会触发响应(前提是该对象的属性为响应式属性)

3.在vue进行初始化时会对data对象进行响应式转化,

 响应式属性的属性值发生变化是,会触发响应,同时如果这个变化的值中包含对象,那么会对这个值进行响应式转化

4.对一个响应式属性重重新赋值一个新对象或者新数组,本质上是属性值(对象指针或者数组指针)发生了变化,会触发响应,同时会对新值进行响应式转化

5.更改对象的现有属性的属性值会触发响应,给对象添加一个新属性或者改变这个新属性的值都不会触发响应。因为新增的属性并不是响应式属性

  要想给对象动态新增响应式属性,使用set方法

6.更改数组的现有元素的元素值不会出发响应,给数组新增新元素也不会触发响应。因为数组元素不能作为响应式属性。

  但如果数组元素的元素值为对象,这个作为元素值的对象的属性为响应式属性,对象的属性值发生变化会触发响应。

  要想让数组变化触发响应,使用set方法或者vue变异数组操作函数

7.数组元素的变化和对象的新增属性虽然不会触发响应,但如果在同一个处理过程中有响应式属性发生了变化,从而触发了响应,那么非响应式属性以及数组元素的变化也会反映到画面中去

8.Vue 不允许动态添加根级响应式 属性,

9.触发响应的条件:1,响应式属性的值发生变化。2,响应式属性在DOM渲染时被watcher实例记录为依赖。如果数据在DOM中没有被用到,就不会被watcher依赖,也就不想触发响应

<script>
export default {
  data() { //data内的所有的对象(包括子对象和数组内的对象)的属性转化为响应式属性
    return {
        obj: {
            a:1 // 响应式属性
        },
        arr:[
          {a:999}, //作为数组元素值的对象的属性也是响应式属性
          1111
        ]
    }
  },
  methods: {
      change1() {
        this.obj.a = 2 //响应式属性发生变化,触发响应
      },
      change2() {
        this.obj.b = 2 //新增属性b为非响应式属性,此处不会触发响应
      },
      change3() {  //新增一个响应式属性
        this.$set(this.obj, b, 2) //通过set方法新增的属性为响应式属性,会触发响应
      },
      change4() {  //新增多个响应式属性,本质为赋值了一个新对象,属于属性值的变化,触发响应
        this.obj = Object.assign({}, this.obj, { b: 2, c:3, d:4 })
      },
      change5() {
        this.obj =  {
          a:1,
          b:2,
          c:3,
          d:4
        }//给根级响应式属性obj重新赋值一个对象,新对象新指针,属性值发生变化,触发响应,同时对新对象进行响应式转化
      },
      change6(){
        this.arr[1] = 999  //数组元素值的变化不会触发响应
      },
      change7(){
        this.$set(this.arr, 1, 999) //通过set方法改变数组元素值的会触发响应
      },
      change8(){
        this.$set(this.arr, this.arr.length, 1999) //通过set方法新增数组元素的会触发响应
      },
      change9(){
        this.arr.push(1999) //通过vue数组操作变异方法改变数组的会触发响应
      },
      change10(){
        this.arr[0].a = 888 //作为数组元素值的对象的属性也是响应式属性,会触发响应
      },
      change11(){
        this.arr[0] = {a:888}  //给数组元素重新赋值一个新对象,相当于数组元素值的变化,不会触发响应,新对象也不会进行响应式转化
        this.arr[0].a = 777   //因为新对象没有进行响应式转化,a属性不是响应式属性,不会触发响应
      },
      change12(){
        this.obj.a = 3  //相应式属性,会触发响应
        this.obj.e = 5  //新增属性为非响应式属性,不会触发响应,但是上面已经触发了响应,所以此非响应式属性的修改也会反映到画面上
      }
  }
}
</script>

 

posted on 2020-09-17 13:13  豁然高  阅读(243)  评论(0编辑  收藏  举报