大家好,今天我给大家讲解一下Vue中的数据劫持是如何实现的
1.在这之前呢,不知道大家知不知道 Object.defineProperty 这个属性呢,如果知道的话,请忽略这一段。
而在这个 descriptor 有很多的属性,还有 get 和 set 的方法,这里就介绍了 get 和 set 这两个方法,其它的可以去官网了解一下。
get:
用作属性的吸气剂或undefined
没有吸气剂的函数。当访问该属性时,将调用该函数而无需使用参数,并且将其this
设置为访问该属性所通过的对象(由于继承,它可能不是在其上定义该属性的对象)。返回值将用作属性的值。
默认为undefined
。set: 用作属性的setter的函数,或者
undefined
如果没有setter 的函数。将属性分配给该函数时,将使用一个参数(将值分配给该属性)并将this
该对象设置为分配该属性的对象来调用此函数。
默认为undefined
。
这个就是官网的介绍啦,就我的个人理解
废话不多说,我们来试验一下。
let obj = { name: ‘小明‘, age: 21 } function fun(obj,name){ let value = obj[name] Object.defineProperty(obj,‘name‘,{ //get 方法就是每次获取这个属性的值时,执行的方法 get(){ console.log(‘我是 get 中的‘) return ‘我是 get 获取的‘ + value }, //set 方法就是每次设置这个属性的值时,执行的方法 set(newVal){ //newVal是给当前的值从新赋值的值,也就是新值 console.log(‘我是 set 中的‘) value = ‘,我是 set 设置的‘ + newVal } }) } fun(obj,‘name‘) console.log(obj.name) //打印两次 1、我是 get 中的 2、我是 get 获取的小明 obj.name = ‘小红‘ //打印一次 1、我是 set 中的 console.log(obj.name) //打印两次 1、我是 get 中的 2、我是 get 获取的,我是 set 设置的小红
2、Vue 中的数据劫持也就使用了这样的方法,让我们看看 Vue 中是如何实现的吧!
/** * 数据劫持 */ class Observer{ constructor(data) { this.observer(data); } observer(data){ //如果是对象才观察 if(data && typeof data === ‘object‘){ for (let key in data) { //循环 data 中的所有子项 this.defineReactive(data,key,data[key]); } } } //实现数据劫持 defineReactive(obj,key,value){ this.observer(value); //如果传进来的参数是对象,就回调一下这个函数,就是一个递归函数 let dep = new Dep(); //给每一个属性都添加一个具有发布和订阅的功能 Object.defineProperty(obj,key,{ get(){ //创建watcher时,会获取到对应的内容 并且把watcher放到了全局上 Dep.target && dep.addSub(Dep.target); return value; }, set: (newVal)=>{ if(value !== newVal){ this.observer(newVal); //给设置的新值也加上 get set 方法 value = newVal; dep.notify(); //执行观察者更新时的函数 } } }) } }
上面就是Vue中实现数据劫持的过程,当然,数据劫持中的 watcher 观察者, Dep 发布和订阅这里就不介绍了,下一篇在为您介绍。
原文:https://www.cnblogs.com/nie5135257/p/12110988.html