> 文章列表 > vue的响应式原理(1)- 监听对象

vue的响应式原理(1)- 监听对象

vue的响应式原理(1)- 监听对象

什么是响应式

通俗易懂的形容一下:比如我说一,你就就说二,我说一次一,你回答我一次二这就是响应式。

vue的响应式原理(1)- 监听对象

在设计框架过程中,通过修改数据以后,视图同步更新这就是响应式。
那么如何实现一个响应式呢?

  1. 你首先要听到我说一,你才回答二(监听对象操作,执行相应的动作)

监听对象的操作

// 一个对象
let obj = { name:"韩程远",age:18};
console.log(obj)
//对对象进行操做
obj.name = "韩大";
obj.age = 100;
delect obj.name;

那么我们想每次对象操作完以后自动输出这个对象我们怎么实现呢?

obj.name = "韩大"
console.log(obj)
obj.age =  20
console.log(obj)
// 这样操作不太行吧。

ES5中通过Object.defineProperty 来监听属性(vue2)

监听单个属性的方式。

Object.defineProperty(obj,"name",{get(){console.log(`监听到obj的name发生被访问了`)},set(){console.log(`监听到obj的name发生被设置了`)}
})   

监听obj所有属性的方式

let obj = {name: "韩程远",age: 18
}
Object.keys(obj).forEach(keys => {let value = obj[keys]Object.defineProperty(obj, keys, {get() {return value},set(newVal) {value = newValconsole.log(`监听到obj的${keys}发生被设置了`)}})
})
obj.name = "韩大"
obj.age =30
console.log(obj.name)
console.log(obj.age)

vue的响应式原理(1)- 监听对象
缺点

Object.defineProperty设计之初并不是用来监听,劫持一个对象中的属性。

  1. 只是想用来定义普通属性,后面强行变成了数据属性的描述
  2. 其次如果我们像监听更加丰富的操作比如,在这个对象原来的基础上新增属性、删除属性,那么 这个方法是无能为力的。
    vue的响应式原理(1)- 监听对象

在ES6中新增的Proxy类,来代理对象。

  1. 所有的监听对象的相关操作,我们都可以用代理来监听对象。
  2. 所有的操作,全部用代理对象来完成。
  3. 代理对象会自动修改对象。
    vue的响应式原理(1)- 监听对象
const obj = {name:"韩程远",age:18}// Proxy 接受两个参数
// 1. 代理对象
// 2. 捕获器对象
const objProxy = new Proxy(obj,{})
console.log(objProxy.name)
console.log(objProxy.age)// 通过代理对象设置值
objProxy.name = "韩程";
objProxy.age="22";console.log(objProxy)
console.log(obj)

通过Proxy监听对象的操作

const obj = {name:"韩程远",age:18}// Proxy 接受两个参数
// 1. 代理对象
// 2. 捕获器对象
const objProxy = new Proxy(obj,{// 获取值得捕获器// 当用户获取值得时候自动回调,objProxy.name 自动get()// 接受三个参数  // target ---> objProxy 所代理得对象    // key --- > 对象的key// receiver ---> 当前代理的对象 get(target,key,receiver){console.log(`监听到obj的${key}发生被获取了`)return target[key]},// 设置值的回调函数自动会掉 objProxy.name = "韩" // 接受四个参数 target key newval  receiver// newVal 设置的值。set(target,key,newVal,receiver){console.log(`监听到obj的${key}发生被设置了`)target[key]= newVal;}
})
console.log(objProxy.name)
console.log(objProxy.age)obj.age = 20
obj.name = "韩大"
console.log(objProxy)

vue的响应式原理(1)- 监听对象
vue的响应式原理(1)- 监听对象

在Object.defineProperty中是不能监听到新增和删除操作呢,那么Proxy如何监听到呢?

新增属性会直接被Proxy给监听到
vue的响应式原理(1)- 监听对象
删除属性可以通过Proxy.deleteProperty来监听到

 // 监听到delect 捕获器deleteProperty(target,key){console.log(`监听到objProxy的${key}的delect操作`,target)delete target[key]}

如果我们想判断一个属性是否在 Proxy对象里面?

// obj 的 in操作
// 如何用代理的方式监听到呢?
// 监听in方法的捕获器,has捕获器
// 接受两个参数  target 和 keyhas(target,key){console.log(`监听到objProxy的${key}的in操作`,target)return key in target},

vue的响应式原理(1)- 监听对象