浅谈vue数据劫持(2)

举报
vike 发表于 2021/10/29 17:16:48 2021/10/29
【摘要】 前言:上一篇讲解了defineProperty方法今天来讲讲proxyvue3中数据劫持使用了proxy主要是因为defineProperty有几项缺点新增属性,删除属性直接通过下标修改数组defineProperty缺点讲解//先回顾上期知识点 let person = { name:'vike', age:5 }​ // 回顾上篇de...

前言:

  • 上一篇讲解了defineProperty方法今天来讲讲proxy

  • vue3中数据劫持使用了proxy主要是因为defineProperty有几项缺点

    • 新增属性,删除属性
    • 直接通过下标修改数组
  • defineProperty缺点讲解

    //先回顾上期知识点    
       let person = {
            name:'vike',
            age:5
        }// 回顾上篇defineProperty方法
        let p = {}
        // name属性
        Object.defineProperty(p,'name',{
            get(){
                console.log('读取name属性')
                return person.name
            },
            set(newValue){
                console.log('修改name属性')
                person.name = newValue
            }
        })
        // age属性
        Object.defineProperty(p,'age',{
            get(){
                console.log('读取age属性')
                return person.age
            },
            set(newValue){
                console.log('修改age属性')
                person.age = newValue
            }
        })
    

image-20210810093626476.png

  • 新增属性

    • 没有进行数据劫持 不能成为响应式数据

image-20210810093922717.png

  • 删除属性

    • 使用delete关键字删除属性,返回flase。
    • delete 删除会返回true或者flase。删完了为true,删不掉为false
    • 在Object.defineProperty配置项内多加一行configurable:true,即可删除
    • delete删除p上属性不会影响person上的属性,主要原因是无法捕获这个变化

image-20210810094133057.png

image-20210810094606508.png

proxy讲解

  • window.Proxy为内置函数

    • 使用实例
        let person = {
            name:'vike',
            age:5
        }// proxy作用  让p映射person 第一个参数为要映射的对象 第二参数可为空对象占位
        let p = new Proxy(person,{})
    

image-20210810095731094.png

-   Proxy里的Handler 对属性进行增删改查操作靠这里面的配置

-   Proxy里的Target 属性

    -   取值方法 p.name p.age

-   新增 修改 删除 proxy代理实现

image-20210810100449035.png

-   proxy捕获数据

    ```
     // 源对象
        let person = {
            name:'vike',
            age:5
        }
    ​
        // 代理对象
        let p = new Proxy(person,{
            // get 上有两个参数 target是newProxy传入的对象 propName是读取的属性
            // 读取属性触发
            get(target,propName){
                console.log(`读取了${propName}属性`)
                return target[propName]
            },
            // set上新增了newValue属性 修改和新增触发
            set(target,propName,newValue){
                console.log(`修改了${propName}属性`)
                target[propName] = newValue
            },
            // deleteProperty 删除属性触发
            deleteProperty(target,propName) {
                console.log(`删除了${propName}属性`)
                delete target[propName]
            }
        })
    ```

image-20210810102150988.png

-   delete p.name返回false是因为deleteProperty方法没返回,只要`return delete target[propName]`

### Reflect 介绍

-   ES6新增

-   ECMA正尝试把Object上的方法移植到Reflect上

image-20210810104307333.png

-   Reflect方法上也包含defineProperty 且有返回值 true表示成功,false表示失败

    ```
        let person = {
            name:'vike',
            age:5
        }
    ​
        let p1 = Reflect.defineProperty(person,'sex',{
            get() {
                return '男'
            }
        })
    ​
        let p2 = Reflect.defineProperty(person,'sex',{
            get() {
                return '女'
            }
        })
    ​
        console.log(p1,p2)
    ```

image-20210810104738379.png

-   对比Object.defineProperty 会直接报错且不执行下面代码

    ```
        let person = {
            name:'vike',
            age:5
        }
    ​
        Object.defineProperty(person,'sex',{
            get() {
                return '男'
            }
        })
    ​
        Object.defineProperty(person,'sex',{
            get() {
                return '女'
            }
        })
    ```

image-20210810105021217.png

总结

  • Reflect和Object来说,框架封装更需要健壮性强的Reflect
  • Proxy处理响应式数据更具优势
  • Object.defineProperty那些缺点在vue框架里也提供了相应的api进行解决
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。