vue2和vue3的代理拦截(数据劫持)

一、vue2的数据劫持

Object.defineProperty

1.第一个参数为要访问的对象名

2.第二个参数要操作的属性,这个键名可以是还未在对象中设置的

3.第三个参数为一个对象,可以对这个属性进行设置

writable:是否允许修改这个值

configurable:是否允许删除这个值

enumerable:是否允许遍历这个值

代码示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        let person = {
            name:'wtx',
            age:18
        }
        Object.defineProperty(person,'sex',{
            // 定义sex属性对应的值
            value:'girl',
            // 是否允许修改这个值  默认为false,不允许修改  true为允许修改
            writable:true,
            // 是否允许删除这个值  默认为false,不允许删除  true为允许删除
            configurable:false,
            // 是否允许遍历这个值  默认为false,不允许遍历  true为允许遍历
            enumerable:true
        })
        // 查看sex属性的值
        // girl
        console.log(person.sex);
        // 修改sex属性的值
        person.sex = 'boy'
        // boy
        console.log(person.sex);
        // 删除sex属性
        delete person.sex
        delete person.name
        // name删除成功,但是sex设置了不允许删除
        // {age: 18, sex: 'boy'}
        console.log(person);
        // 遍历person对象的键名,设置了true,允许遍历
        // ['age', 'sex']
        console.log(Object.keys(person));
    </script>
</body>
</html>
  1. 数据劫持实现vue的响应式原理

  1. get和set方法,当访问到设置的属性时,会调用get方法;当属性值被修改时,会调用set方法

let obj = {
    name:'华为',
    price:'4999',
    color:'black'
}
let val = '中国'
// 实现vue的响应式原理
Object.defineProperty(obj,'addr',{
    // 当访问该属性时,会调用此函数
    get() {
        console.log('有人读取了这个属性');
        return val
    },
    // 当属性值被修改时,会调用此函数
    set(value) {
        console.log('有人修改了这个值');
        // 这是修改后的值
        console.log(value);
        val = value
    }
})
// 4999
console.log(obj.price);
// 有人读取了这个属性 中国
console.log(obj.addr);
obj.made = '地球'
// 地球
console.log(obj.made);
// {name: '华为', price: '4999', color: 'black', made: '地球'}
console.log(obj);

二、vue3的数据劫持

  1. proxy

let p = new Proxy(person,{get(target,key) {}})

第一个参数person为对象名 target为目标对象 key为属性名

  1. 代码示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>proxy</title>
</head>
<body>
    <script>
        let person = {
            name:'wtx',
            age:23
        }
        let p = new Proxy(person, {
            get(target,key) {
                console.log('有人访问了对象的属性'+key);
                // 目标对象
                console.log(target);
                // 目标对象的属性
                console.log(key);
                // 目标对象的属性对应的属性值
                return target[key]
            }
        })
        // Proxy {name: 'wtx', age: 23}
        console.log(p);
        // 只要访问了对象的属性,就会触发get函数
        // 有人访问了对象的属性 {name: 'wtx', age: 23} name wtx
        console.log(p.name);
        // 有人访问了对象的属性 {name: 'wtx', age: 23} age 23
        console.log(p.age);
        // 如果访问的属性不存在,那就返回undefined
        // 有人访问了对象的属性 {name: 'wtx', age: 23} sex undefined
        console.log(p.sex);
    </script>
</body>
</html>

当要访问的属性不在对象中时,设置抛出异常。

// 处理访问的属性不在对象中的情况
let good = {
    name:'小米手机',
    price:3999,
    color:'白色'
}
let p2 = new Proxy(good, {
    get(target,key) {
        // 如果访问的属性名在对象中 则返回属性值
        if(key in target) {
            console.log('有人访问了对象的属性'+key);
            return target[key]
        }else {
            // 如果访问的属性名不在对象中,则抛出异常
            throw new Error('属性不在对象中')
        }
    }
})
// 有人访问了对象的属性color 白色
console.log(p2.color);
// 抛出异常 属性不在对象中
console.log(p2.address);
  1. proxy使用案例

去掉对象中某个属性的首尾空格

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>课前测</title>
</head>
<body>
    <script>
        // 匹配首位空格的正则
        let reg = /^\s+|\s+$/g
        let person = {
            name:'wtx',
            age:20
        }
        let p = new Proxy(person, {
            // 获取
            get(target,key) {
                console.log('有人访问了这个属性');
                return target[key]
            },
            // 修改
            set(target,key,value) {
                // 如果有空格,则去掉首尾空格
                if(reg.test(value)==true) {
                    target[key] = value.trim()
                }else {
                    console.log(222);
                    target[key] = value
                }
                
            }
        })
        p.name = '  cmh  '
        console.log(p.name);
    </script>
</body>
</html>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值