源码

模拟Vue2 实现响应式

直接使用一个 .html 模拟

<!DOCTYPE html>
<html>
    <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',{
                configurable:true,
                get(){ //有人读取name时调用
                    return person.name
                },
                set(value){ //有人修改name时调用
                    console.log('有人修改了name属性,我发现了,我要去更新界面!')
                    person.name = value
                }
            })
            Object.defineProperty(p,'age',{
                get(){ //有人读取age时调用
                    return person.age
                },
                set(value){ //有人修改age时调用
                    console.log('有人修改了age属性,我发现了,我要去更新界面!')
                    person.age = value
                }
            }) 
        </script>
    </body>
</html>

在 F12 的控制台分别执行下面的内容,观察变化:

person
p
p.name = '李四'
p.age = 90
p.sex = '男'

模拟Vue3 实现响应式

proxy 代理
英[ˈprɒksi] 美[ˈprɑːksi]

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Document</title>
    </head>
    <body>
        <script type="text/javascript" >
            //源数据
            let person = {
                name:'张三',
                age:18
            }

            //模拟Vue3中实现响应式
            //#region 
            //window.Proxy
            const p = new Proxy(person,{ //捕获 person属性 变化
                //有人读取p的某个属性时调用
                //    target: 目标对象
                //    propName: 目标对象的属性名
                get(target,propName){
                    console.log(`有人读取了p身上的${propName}属性`)

                    return target[propName]
                },

                //有人修改p的某个属性、或给p追加某个属性时调用
                set(target,propName,value){
                    console.log(`有人修改了p身上的${propName}属性,我要去更新界面了!`)

                    target[propName] = value
                },

                //有人删除p的某个属性时调用
                deleteProperty(target,propName){
                    console.log(`有人删除了p身上的${propName}属性,我要去更新界面了!`)

                    return delete target[propName] //如果真删掉,返回true 否则,返回false
                }
            })
        </script>
    </body>
</html>

在 F12 的控制台分别执行下面的内容,观察变化:

person
p.name = 'www'
delete p.name
p.sex = '男'