对数据响应式的理解

157 阅读2分钟

Vue数据响应式

数据响应式,简单来说就是根据数据的变化而产生响应的功能。在Vue2中是如何实现的呢?

getter和setter

有如下一段代码中:

let person = {
   firstName: 'Harry',
   lastName: 'Potter',
   name() {
       return this.firstName + this.lastName;
   },
   age: 18
};

由于name是一个函数,因此想要得到person的name就必须用person.name()获取,如何在不使用括号的情况下获得person的name?

在name前加上get,意为读这个函数,再调用时即可不用加()

   get name() {
       return this.firstName + this.lastName;
   }
   

如何让name可以被赋值
比如person.name = 'JK Rowling',然后输入person.firstName显示'JK'
需要在person对象中加入set函数.
在输入person.name = 'JK Rowling'后,就会call一下set函数

 set name(xxx) {
    this.firstName = xxx[0]
    this.lastName = xxx.slice(1)
 }

Object的defineProperty属性

此属性,简单来说就是直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。详细描述见MDN文档

如果已经将一个对象定义完成了,但是想在其中添加新属性,可用在定义完成之后用。
Object.defineProperty(obj, prop, descriptor)

Vue2 组合使用

Vue2中使用defineProperty这个API,为Vue中的数据添加代理和监听。

let myData = {n:0}
let data_p = proxy({ data:myData })  //这里就是代理,对mydata的读写,全由另一个对象data_p来负责

function proxy({data}){                      
  let value = data.n
  Object.defineProperty(data, 'n', {   //通过设置data的属性为n,来进行监听,之前的属性n被移除,这样当data变化时,就可以通过setter实现响应。这个过程就是监听。同时也避免了暴力直接修改n的值带来的问题。
    get(){
      return value
    },
    set(newValue){
      if(newValue<0)return
      value = newValue
    }
})

总结

Vue 2 通过Object.defineProperty实现数据响应,具体做法是给对象添加属性。添加getter和setter,用于对属性的监控。