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

响应式编程是一种当数据变化时,视图自动更新的技术。文章通过实例解释了如何使用`Object.defineProperty`来监听和响应对象属性的变化,然后介绍了`ES6`的`Proxy`如何更全面地代理和捕获对象的各种操作,包括属性访问、设置、删除和新增,以实现更强大的响应式功能。同时指出了`Object.defineProperty`的局限性和`Proxy`的优势。
摘要由CSDN通过智能技术生成

什么是响应式

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

响应式

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

  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
    },

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值