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 = newVal
            console.log(`监听到obj的${
      
      keys}发生被设置了`)
        }
    })
})
obj.name = "韩大"
obj.age =30
console.log(obj.name)
console.log(obj.age)

在这里插入图片描述
缺点

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

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

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

  1. 所有的监听对象的相关操作,我们都可以用代理来监听对象。
  2. 所有的操作,全部用代理对象来完成。
  3. 代理对象会自动修改对象。
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/5dcbb7517f7749fea4d206d2f07dc06a.png
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)

在这里插入图片描述
在这里插入图片描述

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

新增属性会直接被Proxy给监听到
在这里插入图片描述
删除属性可以通过Proxy.deleteProperty来监听到

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

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

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

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43198727/article/details/129904327