zoukankan      html  css  js  c++  java
  • 百度前端技术学院---vue动态数据绑定-3

    回调中如何实现冒泡?

    /*
    通过将记录每个属性的父级,当属性值变化,逐级寻找回调
    最开始,打算在data上附加父级信息,后来感觉头快爆炸了,实现太麻烦,无法通过属性来获取父级对象名字,
    最后想到元素的parentNode , 不需要做成链式的,每个子属性,只需要记住它的父元素就行了.
    */
    	(function(){
    		window.Observer = function(data){
    			this.data=data;
    			this.makeObserver();
    		};
    		var oP = Observer.prototype;
    		oP.watchArr = {};
    		//保存父级信息
    		oP._parentNode = {};
    		//父级初始化为空
    		oP._parent = '';
    		oP.makeObserver = function(){
    			for(var key in this.data){	
    				if(!this.data.hasOwnProperty(key))return;
    				var val = this.data[key];
    				//设置父级表
    				this._parentNode[key] = this._parent;
    				if(typeof val === 'object'){
    					oP._parent = key;
    					//递归时将当前key设置为父级
    					new Observer(val);
    				};
    				this.setObserver(val,key);
    			};
    		};
    
    		oP.setObserver = function(val,key){
    			var that = this;
    			Object.defineProperty(that.data,key,{
    				enumerable: true,
        			configurable: true,
    				get:function(){
    					return val;
    				},
    				set:function(newValue){
    					if(typeof newValue === 'object'){
    						new Observer(newValue);
    					};
    					if(val === newValue)return;
    					//触发set时,执行冒泡
    					oP.bubbleWatch(key,newValue,val);
    					val = newValue;
    				}
    			});	
    		};
    		oP.bubbleWatch = function(key,newValue,val){	
    			if(this.watchArr[key]){
    			//如果监听表存在key,执行一次
    				this.implementWatch(key,newValue,val);
    			//如果冒泡选项为false,则return
    				if(!this.watchArr[key].options.bubble)return;
    
    			};
    			//剩下冒泡为true的,递归调用父级属性的回调
    			parentKey = this.getParent(key);
    			if(parentKey)this.bubbleWatch(parentKey,newValue,val);
    		};
    		oP.getParent = function(key){
    			var parent = this._parentNode[key];		
    			return parent;
    		};
    		oP.implementWatch = function(key,newValue,val){			
    			for(var i = 0;i<this.watchArr[key].fn.length;i++){		
    					this.watchArr[key].fn[i](newValue,val);
    				}
    		};
    		oP.$watch = function(key,fn,options){
    			options = extend(options,{
    				bubble:false
    			});
    			if(!this.watchArr[key]){
    				this.watchArr[key]={
    					options:options,
    					fn:[]
    				};
    			};		
    			this.watchArr[key].fn.push(fn);
    			return this;		
    		};
    	})()
    
    var app2 = new Observer({
        name: {
            firstName: 'xiao',
            lastName: {
            	ming:"ming",
            	liang:"liang"
            }
        },
        age: 25
    });
    
    app2.$watch('name', function (newName) {
        console.log("name",newName)
    });
    
    app2.$watch('firstName', function (newName) {
        console.log('firstName',newName)
    },{bubble:true});
    
    app2.$watch('ming', function (newName) {
        console.log('ming',newName)
    });
    
    
    app2.data.name.firstName = 'll';
    app2.data.name.firstName = 'lll';
    app2.data.name.lastName.ming = 'hong';
    
    /*
    输出:
    firstName ll ---触发watch
    name ll --- 冒泡到name上触发name的回调函数
    firstName lll
    name lll
    ming hong --- 没有冒泡,所以未触发name上的回调
    
    */
    
    function extend(x,y){
        var y=y||{};
    	for(var i in x){
    		if(typeof x[i] === "object"){
    			y[i] = (x[i] instanceof Array) ? [] : {};
    			extend(x[i],y[i])
    		}else {
          y[i] = x[i];
         }
    	};
    	return y;
    }	
    
    
    
  • 相关阅读:
    OC中nil、Nil、NULL、NSNull的区别
    SOJ 1050. Numbers & Letters
    SOJ 1009. Mersenne Composite N
    SOJ 1006. Team Rankings
    SOJ 1036. Crypto Columns
    SOJ 1151. 魔板
    SOJ 1007. To and Fro
    SOJ 1150.简单魔板
    SOJ 1051 Biker's Trip Odometer
    SOJ 1176 Two Ends
  • 原文地址:https://www.cnblogs.com/LiangHuang/p/6498337.html
Copyright © 2011-2022 走看看