vue数据响应式

89 阅读2分钟

什么是vue数据响应式

“vue数据响应式”,是指当数据改变后,Vue 会通知到使用该数据的代码。例如,视图渲染中使用了数据,数据改变后,视图也会自动更新。

Vue的数据响应式


<div id="root">{{ name }}</div>


var vm = new Vue({
  el: '#root',
  data: {
    name: 'zzq'
  }
})

如果修改vm.name或者修改后面对象的name,那么UI当中的name被更新了,这就是响应。

在Vue2 通过Object.defineProperty来实现数据响应式。类似下面的原理

let obj4 = {
  姓: "曾",
  名: "志强",
}
var _xxx = 0

Object.defineProperty(obj4,'xxx',{
  get() {
    return _xxx
  },
  set(value) {
    _xxx = value
  }
    
})
obj4.姓名 = '刘诗诗'
console.log(obj4.姓名)

上面的obj4在上面代码当中必须要有一个 ​xxx,才能够监听和代理obj4.xxx。

如果说前端开发者在写代码的过程当中,忘记了给​xxx​怎么办?

Vue会给出一个警告。

new Vue({
  data: {},
  template: `<div>{{xxx}}</div>`
}).$mount("#app");

上面代码当中,​data是一个空的,然后再写了一个​xxx,Vue一旦发现是值为​undefined​​或者是​null​​那么页面上将不会显示

在这里控制台会出现一个报错,xxx未被定义

Vue的关键点来了

vue只会检查第一层的属性

const vm = new Vue({
  data: {
    obj: {
      a: 0 // obj.a 会被 Vue 监听 & 代理
    }
  },
  template: `
    <div>
      {{obj.b}}
      <button @click="setB">set b</button>
    </div>
  `,
  methods: {
    setB() {
      this.obj.b = 1; //请问,页面中会显示 1 吗?
    }
  }
})
vm.$mount("#app");

这一回我们将a放在​data​这个对象里面,然后在页面中显示的是对象的b,这样可以完美的避开Vue的警告。

因为Vue在检查的时候只检查了第一层也就是​data​部分, 正常来说的话,Vue会正常的监听​data​,同时也会正常的监听​a​,只要写了都会进行监听。

如果我们对​vm.obj.a​进行变换,是可以正常的翻译到这个视图里面的,但是这里写的是​obj.b,当​button​按钮被点击将会触发​setB​,然后将1赋值给b并展示在页面上面。

答案当然是没有反应,因为初始化时只告诉了​vm ​obj​里面有一个a,vue当然就只监听了​obj​里面的a,b不存在当然也就不会去监听了。

解决方案 通过vue的this.$set和Vue.set

new Vue({
  data: {
    obj: {
      a: 0 
    }
  },
  template: `
    <div>
      {{obj.b}}
      <button @click="setB">set b</button>
    </div>
  `,
  methods: {
    setB() {
      //this.$set(this.obj,'b',1);
      Vue.set(this.obj,'b',1)
    }
  }
}).$mount("#app");

开始obj.b不存在,所以不会监听,在通过操作后我们需要监听它的变化,因此我们要告诉vue去监听它,这样监听后,操作了obj.b的值的变化,视图也会刷新