vue2、vue3数据响应原理

80 阅读1分钟

数据响应原理

Object.defineProperty

Vue2数据响应核心是使用了Object.defineProperty方法(IE9+)在对象中定义属性或者修改属性,其中存取描述符很关键的就是get和set,提供给属性getter和setter方法

可以看下面例子,我们拦截到了数据获取以及设置

let obj ={
            _name:'zhangsan'
        }
        
        /* 不支持ie8以下 */
        /* Object.defineProperty 可以对对象的属性进行劫持 */
        /* configurable 属性是否能被删除 默认为true,可以被删除 */
        /*  value就是对象属性的默认值 优先级比定义的优先级大 为设置默认值为undefined */
        
        // Object.defineProperty(obj,'name',{
        //     get (){
        //         console.log('我在获取值');
        //         return this._name
        //     },
        //     set (v){
        //         console.log('我设置的值是',v);
        //         this._name = v
        //     }
        // })
        
        /* defineProperties多个拦截 */
        
        Object.defineProperties(obj,{
            name:{
                configurable:false,
                writable:false,
                value:'baobao',
                // get (){
                //     console.log('我在获取值');
                //     return this._name
                // },
                // set (v){
                //     console.log('我设置的值是',v);
                //     this._name = v
                // }
            }
        })

        document.write(obj.name + '<br/>')
        obj.name = 'waner'
        document.write(obj.name)

vue3原理proxy

通过Proxy,我们可以对设置代理的对象上的一些操作进行拦截,外界对这个对象的各种操作,都要先通过这层拦截。(和defineProperty差不多)

let p ={
        name:'zhansan',
        age:30
    }
    let p2 = {
        get(obj,key){
            /* obj是源对象 key是对象属性   */
            return obj[key]
        },
        set(obj,key,val){
             /* obj是源对象 key是对象属性 val是属性的值*/
            if(val!=this.name){
                console.log('我把:'+obj[key]+'改成了:'+val);
            obj[key] = val;
            }
            
        }
    }

    /* p代表源对象 p2代表需要操作的对象 */
    let proxy1 = new Proxy(p,p2)
    proxy1.name = '李四'
    document.write(proxy1.name+'<br>')
    document.write(proxy1.age+'<br>')
    
    //页面打印 李四\30