Vue数据响应式的理解

353 阅读2分钟

在使用Vue进行开发时,一旦页面上展示的数据在js中进行了更新,那么并不需要开发者编写有关渲染的代码,Vue会自动将页面对应的数据更新。因为Vue底层对实例化时声明的数据(属性)都进行了监听和代理,即当数据变化时,Vue会立刻监听到变化,并调用渲染操作。

通俗来讲就是当修改vm的属性,那么页面会根据修改的内容自动改变。
使用Object.defineProperty(obj , 'n' , {....})监听

//一个简单的例子
new Vue(
    data: {
    obj: {
        a: 0
        }
    }
    template: `
      <div>
        {{obj.b}} //如果不加Vue.set或者this.$set,定义的是a,打印的是b。但不会报错,只会显示空白
      </div>
    `,
    methods: {
    setB() {
        Vue.set(this.obj, 'b', 1) //与下面一句等价
        this.$set(this.obj, 'b', 1) //加了之后新增b,并且把1赋值给b,会自动更新页面
    }
})

会有两个bug:

  1. data里面如果啥都没写,Vue会给出一个警告,不会显示null或者undefined,页面会显示空白。
  2. 如果写了一个属性a,但是后续改了一个属性b。那么vue不会去监听这个属性b,但是不会报错。vue之后检查第一层属性,只检查a。 解决方法:
  3. 把key都声明好,后面不再添加新的属性。
  4. Vue.set或者this.$set添加属性。会直接新增这个key;如果没有创建代理和监听,Vue.set会自动创建代理和监听(this.set不会自动添加监听);会触发UI更新,但不会立即更新数组的变更方法如果data里面声明的是数组,就没办法声明全部key(下标)。为了避免每次改数组都需要Vue.set或者this.set不会自动添加监听);会触发UI更新,但不会立即更新 **数组的变更方法** 如果data里面声明的是数组,就没办法声明全部key(下标)。为了避免每次改数组都需要Vue.set或者this.set。Vue将数组默认的方法篡改了。方便数组的增删。原理也是用Object.defineProperty的set方法。
  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse() 练习题1
//html代码
<div id="app">
    <span class=span-a>
      {{obj.a}} 
    </span>
    <span class=span-b>
      {{obj.b}}
    </span>
  </div>
//js代码 
var app = new Vue({
  el: '#app',
  data: {
    obj: {
      a: 'a',
    }
  },
})
app.obj.a = 'a2'

span-a输出a2,span-b显示空白

练习2

<div id="app">
    <span class=span-a>
      {{obj.a}} 
    </span>
    <span class=span-b>
      {{obj.b}}
    </span>
  </div>
//js代码
var app = new Vue({
  el: '#app',
  data: {
    obj: {
      a: 'a',
    }
  },
})
app.obj.b = 'b'

span-a显示a,span-b显示空白
练习3

<div id="app">
    <span class=span-a>
      {{obj.a}} 
    </span>
    <span class=span-b>
      {{obj.b}}
    </span>
  </div>
//js
var app = new Vue({
  el: '#app',
  data: {
    obj: {
      a: 'a',
    }
  },
})
app.obj.a = 'a2'
app.obj.b = 'b'

span-a显示a2,span-b显示b //异步更新UI的坑(后续再填)