VUE及watcher原理(簡單版)

核心方法:Object.defineProperty

設計模式:數據劫持,監聽者模式

上源碼

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title></title>
	</head>
	<body>
		<button onclick="a()">get</button>
		<button onclick="b()">set</button>
	</body>
</html>
<script type="text/javascript">
	
	//全局watcher容器
	var wathcTarget = null;
	//對象遞歸綁定
	function forObjBind(o){
		for( k in o){
			if( typeof o[k] == 'object' ){
				forObjBind(o[k])
			}else{
				objBind(k,o)
			}
		}
	}
	function objBind(k,o){
		var dsp = new Dsp();
		if(watchTarget){
			dsp.addSub(watchTarget);
			watchTarget = null;
		}
		var v = o[k];
		Object.defineProperty(o,k,{
			enumerable: true,
			get:function(){
				//console.log("get "+k+":", v)
				return v;
			},
			set:function(val){
				//console.log("set "+k+":", val)
				if(v !== val){
					v = val;
					dsp.notify(k);
				}
				v = val;
			}
		})
	}
	//消息訂閱器
	var Dsp = function(){
		this.addSub = function(item){
			this.subs.push(item);
		}
		this.notify = function(k){
			console.log(this.subs)
			this.subs.forEach(function(item){
				item.update(k);
			})
		}
	}
	Dsp.prototype.subs = [];
	//監聽者
	function watcher(render){
		watchTarget = this;
		console.log("newWathche")
		this.update = function(k){
			render(k)
		}
	}
	//VUe
	function Vue(ops){
		this._data = ops.data();
		this.mount = function(){
			new watcher(this.render)
			forObjBind(this._data)
		}
		this.render = function(k){
			console.log("來自監聽的回調" + k + '變了')
		}
	}
	var v = new Vue({
		data(){
			return {
				name:"gaoliang",
				age:35
			}
		}
	})
	
	v.mount();
	
	//獲取
	function a(){
		console.log(v._data.name)
	}
	//設置
	function b(){
		v._data.age = "haha"
	}
</script>

 

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