• vue3--响应式原理


    和vue2对比:

    vue2响应式实现原理:
    对象类型:通过Object.defineProperty()对属性的读取,修改进行拦截(数据劫持)。
    数组类型:通过重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行包裹)。

    Object.defineProperty(data,'conunt',{
    get(){},
    set(){}
    })
    
    • 1
    • 2
    • 3
    • 4

    弊端在 :1、该get和set方法只能监控查询和修改,对新增和删除监控无效,
    2、直接通过下标修改数组,也监控不了

    只能通过2中方法解决

    1:通过this.$set(this.person,'sex','女')
    2:通过Vue.$set(this.person,'sex','女')
    1:通过this.$delete(this.person,'sex','女')
    2:通过Vue.$delete(this.person,'sex','女')
    
    • 1
    • 2
    • 3
    • 4

    数组:
    1:this.$set(this.person.hobby,0,‘逛街’)
    2:this.person.hobby.splice(0,1,'逛街)

    vue3响应式原理:

    直接通过html文件实现vue2和vue3进行对比:
    vue2:
    先在vscode插件中下载open in browser方便直接打开html
    在这里插入图片描述

    <!DOCTYPE html>
    <html lang="">
    
    <head>
        <meta charset="utf-8">
        <title>Document</title>
    </head>
    
    <body>
        <script type="text/javascript">
            // 元数据
            let person = {
                name: '张三',
                age: 18
            }
    
            // 模拟vue2中实现响应式
            let p = {}
            Object.defineProperty(
                p, 'name', {//有人读取name时调用
                get() {
                    return person.name
                },
                set(value) {
                    console.log('有人修改了name属性,我发现了,我要去更新新界面')
                    person.name = value
                }
            }
            )
            Object.defineProperty(
                p, 'age', {//有人读取age时调用
                get() {
                    return person.age
                },
                set(value) {
                    console.log('有人修改了age属性,我发现了,我要去更新新界面')
                    person.age = value
                }
            }
            )
    
        </script>
    </body>
    
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    在这里插入图片描述
    在这里插入图片描述
    可以看到新增和删除无效

    vue3使用es6的新特性Proxy实现:

    <!DOCTYPE html>
    <html lang="">
    
    <head>
        <meta charset="utf-8">
        <title>Document</title>
    </head>
    
    <body>
        <script type="text/javascript">
            // 元数据
            let person = {
                name: '张三',
                age: 18
            }
    
            // 模拟vue2中实现响应式
            // let p = {}
            //#region 
            // Object.defineProperty(
    
            //     p, 'name', {//有人读取name时调用
            //     configurable : true,
            //     get() {
            //         return person.name
            //     },
            //     set(value) {
            //         console.log('有人修改了name属性,我发现了,我要去更新新界面')
            //         person.name = value
            //     }
            // }
            // )
            // Object.defineProperty(
            //     p, 'age', {//有人读取age时调用
            //     configurable : true,
            //     get() {
            //         return person.age
            //     },
            //     set(value) {
            //         console.log('有人修改了age属性,我发现了,我要去更新新界面')
            //         person.age = value
            //     }
            // }
            // )
            //#endregion
    
    //      Vue3中的实现响应式
                const p = new Proxy(person,{
                    get(target,propName){
                        console.log(`有人读取了p身上的${propName}某个属性`,target,propName)
                        return target[propName]
                    },
                    set(target,propName,value){
                        console.log(`有人修改了p身上的${propName}某个属性,我要去更新界面了`,target,propName,value)
                        target[propName] = value
                    },
                    deleteProperty(target,propName){
                        console.log(`有人删除了p身上的${propName}某个属性,我要去更新界面了`,target,propName)
                        return delete target[propName]
                    }
                })
    
        </script>
    </body>
    
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    在这里插入图片描述
    可以看到增删改查都能监控!

    es6新特性使用反射Reflect:

    与直接操作区别,能返回数值表示是否成功,适用于框架封装

    <!DOCTYPE html>
    <html lang="">
    
    <head>
        <meta charset="utf-8">
        <title>Document</title>
    </head>
    
    <body>
        <script type="text/javascript">
            // 元数据
            let person = {
                name: '张三',
                age: 18
            }
    
            // 模拟vue2中实现响应式
            // let p = {}
            //#region 
            // Object.defineProperty(
    
            //     p, 'name', {//有人读取name时调用
            //     configurable : true,
            //     get() {
            //         return person.name
            //     },
            //     set(value) {
            //         console.log('有人修改了name属性,我发现了,我要去更新新界面')
            //         person.name = value
            //     }
            // }
            // )
            // Object.defineProperty(
            //     p, 'age', {//有人读取age时调用
            //     configurable : true,
            //     get() {
            //         return person.age
            //     },
            //     set(value) {
            //         console.log('有人修改了age属性,我发现了,我要去更新新界面')
            //         person.age = value
            //     }
            // }
            // )
            //#endregion
    
    //      Vue3中的实现响应式
                const p = new Proxy(person,{
                    get(target,propName){
                        console.log(`有人读取了p身上的${propName}某个属性`,target,propName)
                        // return target[propName]
                        return Reflect.get(target,propName)
                    },
                    set(target,propName,value){
                        console.log(`有人修改了p身上的${propName}某个属性,我要去更新界面了`,target,propName,value)
                        // target[propName] = value
                       Reflect.set(target,propName,value)
                    },
                    deleteProperty(target,propName){
                        console.log(`有人删除了p身上的${propName}某个属性,我要去更新界面了`,target,propName)
                        // return delete target[propName]
                        return Reflect.deleteProperty(target,propName)
                    }
                })
    
            
    
    
        </script>
    </body>
    
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
  • 相关阅读:
    wpf devexpress post 更改数据库
    CCAA 认证通用基础卷之(一)合格评定基础 第二章合格评定与国家质量基础设施 NQI (National Quality Infrastructure)
    面试素材-结构化
    c++以exception_ptr传递异常
    分享:互信息在对比学习中的应用
    华为云服务
    不仅仅是图书信息管理系统
    字符编码的历史与发展(ASCII, GBK, Unicode)
    vue-element-admin入门①
    亚马逊卖家测评为什么一定要掌握自养号技巧
  • 原文地址:https://blog.csdn.net/qq_43470725/article/details/126082460