Vueの応答式原理/データハイジャックはObjectに基づく.defineProperty実装

2584 ワード

1.vueのデータハイジャック/応答式の原理:Objectに基づく.defineProperty(IE 8以下ではObject.definePropertyはサポートされていません)は、data内のデータをリスニングし、data内のデータが変更されるとビューの変更(再レンダリング)をトリガーします.
let options={
    data:{
        name:"Ace",
        age:18
    },
    render(){

    }
}
class AVue{
    constructor(options){
        this._data=options.data;  // {name:"Ace",age:18}
        this.watchDataChange(this._data,options.render);
    }
    watchDataChange(data,render){  
        let _this=this;
        Object.keys(data).forEach((key)=>{
            _this.dataChange(data,key,render);
            _this.proxyDataChange(key,render);
        })
    }
    proxyDataChange(key,render){  //   ,   options.data.name     ,       options.name     
        let _this=this;
        Object.defineProperty(_this,key,{ // this   key  ,   options.name,options.age
            configrable:true, 
            enumerable:true,
            get:()=>{
                return _this._data[key]
            },
            set:(newVal)=>{
                if(newVal !==val){
                    _this._data[key]=newVal;
                    render();
                }                
            }
        })
    }
    dataChange(obj,key,render){   
        Object.defineProperty(obj,key,{   //options.data.name,options.data.age
            configrable:true,  //        
            enumerable:true,  //        
            get:()=>{
                return obj[key]
            },
            set:newVal=>{
                if(newVal !==val){
                    obj[key]=newVal;
                    render();
                }                
            }
        })
    }
}


//   AVue
let app = new AVue({
    el: '#app',
    data: {
        text: 'text',
        text2: 'text2'
    },
    render(){
        console.log("render");
    }
})

注意:job:'IT'のようなdata内のデータは、実際のテンプレートでは使用されませんが、jobのデータが変更されると(this.job='CEO')、jobのsetterがトリガーされてレンダリングが再実行され、性能の問題があります.vueは、収集に依存することによって、実際のモジュールでデータが呼び出されたときにのみ再レンダリングされるようにします.
2.Object.defineProperty(obj,key,des)プロパティ:オブジェクトに直接新しいプロパティを定義するか、既存のプロパティを変更/取得する役割を果たします.
Object.defineProperty(obj,key,{
    configurable:bool, //           
    enumerable:bool,  //           
    value:any,   //    
    writable:bool,  //      
    get:()=>{return obj[key]},  //  
    set:(newVal)=>{obj[key]=newVal}   //  
});

詳細vueソース解析リファレンスhttps://github.com/answershuto/learnVue/blob/master/docs/%E5%93%8D%E5%BA%94%E5%BC%8F%E5%8E%9F%E7%90%86.MarkDown.