Vue 数据响应式

101 阅读1分钟

数据响应式是什么

用一段简单的代码理解 Vue 的数据响应式:

const vm = new Vue({
  data: {
    n: 0
  },
  template: '<div>{{ n }}</div>'
})
setTimeout(()=>{
  vm.n += 10
  // 修改 vm.n,UI 中的 n 会随着改变
},3000)

一句话概括,即:

当你修改 Vue 中的数据模型时,视图会==自动==进行更新。

原理

const vm = new Vue({data: myData})

当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为getter/setter

这样 Vue 就能让 vm 成为 myData 的代理(proxy),对 myData的所有属性进行监控。

一旦 myData 的属性变了,Vue 就可以通知视图自动更新。

使用时的注意事项

由于 JavaScript 的限制,Vue 不能检测数组和对象的变化。

对象

  1. 由于 Vue 通过Object.defineProperty(obj,'n',{...})的方式监听和代理 obj.n,因此必须一开始就给它一个n
var vm = new Vue({
  data:{
    n:1
  }
})

// `vm.n` 是响应式的

vm.x = 2
// `vm.x` 是非响应式的
  1. 出现对象的嵌套时,可以使用Vue.set或者vm.$set向嵌套对象添加响应式属性。但是更推荐一开始就写好 key。
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; //obj.b 是非响应式的
 	  this.$set(this.obj,'b',2) //obj.b 是响应式的
    }
  }
}).$mount("#app");

数组

由于数组没有办法提前声明所有 key,因此最好使用 Vue 的七个数组 API。

push()pop()shift()unshift()splice()sort()replace()

这七个 API 会自动处理监听和代理,并更新 UI。