【Vue3】第二部分 Vue3中的响应式原理

【Vue3】第二部分 Vue3中的响应式原理



2. Vue3中的响应式原理

2.1 回顾一下模拟Vue2中响应式实现

具体代码

		/* 
            模拟Vue2中响应式实现 
        */
       // 源数据
        let person = {
            name:'Jack',
            age: 18
        }

        // 代理数据
        let p = {}
        Object.defineProperty(p,'name',{
            get()
            {
                console.log('有人读取了name属性');
                return person.name
            },
            set(val){
                console.log('有人修改了name属性');
                return person.name = val
            }
        })
        Object.defineProperty(p,'age',{
            get()
            {
                console.log('有人读取了age属性');
                return person.age
            },
            set(val){
                console.log('有人修改了age属性');
                return person.age = val
            }
        })

2.2 模拟Vue3中响应式实现(Proxy)

演示

在这里插入图片描述

具体代码

  			/* 
            模拟Vue3中响应式
        */
       
        let person = {
            name:'Jack',
            age: 18
        }
        // Proxy 第一个参数:源数据 第二个参数配置
       let p = new Proxy(person,{
           /* 
                get中的参数
                    - 有人读取某个属性时调用
                    - 第一个参数:整个源数据
                    - 第二个参数:属性名
           */
           get(target,propName){
               console.log(`有人读取了${propName}属性`);
                return target[propName]
           },

           /* 
                set中的参数
                    - 有人修改某个属性值或者追加某个属性时调用
                    - 第一个参数:整个源数据
                    - 第二个参数:属性名
                    - 第三个参数:修改后的值
           */
           set(target,propName,val){
                console.log(`有人修改了${propName}属性`);
                return target[propName] = val
           },
           /* 
                deleteProperty中的参数
                    - 有人删除某个属性时调用
                    - 第一个参数:整个源数据
                    - 第二个参数:属性名
           */
           deleteProperty(target,propName){
            console.log(`有人删除了${propName}属性`);
                return delete target[propName]
           }
       })

2.3 Reflect.defineProperty

  let person = {
            name:'Jack',
            age: 18
        }


    /* 
        Object.defineProperty和Reflect.defineProperty的区别
            - 如果出现异常Object.defineProperty会立即报错,单线程,后面代码无法正常运行
            但是Reflect.defineProperty能够继续往下执行,它以返回值的形式告知是否正常运行
    */

    // Object.defineProperty 操作数据
    Object.defineProperty(person,'profession',{
        get(){
            return 'teacher'
        }
    })

    Object.defineProperty(person,'profession',{
        get(){
            return 'student'
        }
    })


    // Reflect.defineProperty 操作数据
    const x1 = Reflect.defineProperty(person,'gender',{
        get(){
            return 'male'
        }
    })  

    console.log(x1); // true

    const x2 = Reflect.defineProperty(person,'gender',{
        get(){
            return 'female'
        }
    })  

    console.log(x2);  // false

2.4 模拟Vue3中响应式实现(Proxy配合Reflect)

演示

在这里插入图片描述

具体代码

 // Vue实现响应式的原理
    // 源数据
    let person = {
        name:'Tree',
        age:18
    }

    //代理数据
    let p = new Proxy(person,{
        get(target,propName){
            console.log(`有人读取了${propName}属性`);
            return Reflect.get(target,propName)
        },
        set(target,propName,val){
            console.log(`有人修改了${propName}属性,修改后的值为${val}`);
            return Reflect.set(target,propName,val)
        },
        deleteProperty(target,propName){
            console.log(`有人删除了${propName}属性`);
            return Reflect.deleteProperty(target,propName)
        }
    })

2.5 Vue3响应式原理总结

  1. 通过Proxy(代理):拦截对象中任意属性的变化,包括:属性值的读写、属性的添加、属性的删除等

  2. 通过Reflect:对被代理对象的属性进行操作

  3. Proxy文档

  4. Reflect文档


2.6 reactive对比ref

从定义数据角度对比

  • ref用于定义基本类型数据
  • reactive是用来定义对象或者是数组类型数据
  • 当然ref也可以去定义对象或者是数组,它内部会自动通过reactive转化为代理对象

从原理的角度分析

  • ref是通过Object.defineProperty()来实现响应式(数据劫持)
  • reactive是通过Reflect.defineProperty()来实现响应式(数据劫持),并且通过Reflect操作源对象内部的数据

从使用的角度上来说

  • ref定义的数据:操作数据需要.value读取数据,但是模板直接读取不需要加.value
  • reactive定义数据:操作和读取数据都不需要加.value

总结

以上就是今天要讲的内容,希望对大家有所帮助!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值