vue watch實現

vue雙向綁定是建立在,給每個屬性建立了getter與setter,在屬性被改變的同時,觸發視圖再渲染
getter是一種獲取屬性值的方法,setter是一種設置屬性值的方法。
當屬性,a = 1被觸發時,setter被觸發,console.log(a)則getter被觸發

實現setter與getter

Object.defineProperty方式

Object.defineProperty(obj, prop, descriptor)有三個參數,解釋如下:
第一個參數,被構造的屬性的this指向的對象
第二個參數,被構造的屬性名
第三個參數,構造的規則(上面的文字鏈接最後面有介紹)

(function(){
	var o = {a:1};
	Object.defineProperty(obj, 'b', {
		get:function(){
			return this.a;
		},
		set:function(val){
			this.a = val;
		},
		configurable: true
	});
	console.log(o.b); // 1
	o.b = 2;
	console.log(o.b); // 2
})()

configurable是指 “b” 是否可以被再配置,默認是false。false的話

Object.defineProperty(o,“a”,{set : function(val){}} ); 再修改時會不起作用或者報錯,一般默認false。

構建vue watch

目標實現,以下是我們想要的達到的效果:

	let vm = new watcher({
            data:{
                a: 1,
            },
            watch:{
                a(newVal, oldVal){
                    console.log('new val:'+ newVal);
                    console.log('old val:'+oldVal);
                }
            }
        })
        vm.a = 2;
  • watcher.js
class watcher{
    constructor(opts){
        this.$data = opts.data;
        this.$watch = opts.watch || {};
        for(let key in this.$data){
            this.setData(key, opts.data[key]);
        }
    }
    setData(_key, _val){
        Object.defineProperty(this, _key, {
            get:function(){
                return this.$data[key]
            },
            set: function(val){
                let oldVal = this.$data[_key];
                if(val === oldVal){
                    return val
                }
                this.$data[_key] = val;
                this.$watch[_key] && typeof(this.$watch[_key]) == 'function' &&(
                    this.$watch[_key].call(this, val, oldVal)
                )
                return val;
            }
        })
    }
}

總結

你也知道vue是一個工程級別的框架,做比較大的項目當然是用vue,react;但是單單做一個展示性的官網或者做個移動端的H5宣傳頁也用上vue嗎?那當然是沒有必要的。

用上這一個watcher類,可以讓你頁面的狀態控制有條理、有跡可循。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章