zoukankan      html  css  js  c++  java
  • MVVM模式源码分析手写实现

    1.demo1.html 

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Document</title>
    </head>
    <body>
    	<!--
    	1.js 内置观察者模式 对象的属性(描述对象)
    	-->
    
    	<script type="text/javascript">
    		var obj = {name:"max",age:30};
    		console.log(obj.name); // name是一个属性
    		// 描述对象(针对对象的属性)
    		// Object.defineProperty 是 Object 的静态方法
    		Object.defineProperty(obj,"name",{ // 参数:观察对象  属性名 描述对象
    			get:function(){ // 获取 阻截访问属性  钩子函数
    				// console.log("max is max");
    				// return "yangyang"
    				return this.value;
    			}, // 将钩子函数的返回值作为 访问属相的返回值(集对象的属性值)
    			set:function(val){ // 设置
    				console.log(val); // 属性值
    				console.log("设置属性值");
    
    				//桥接模式 扩展对象属性的方式
    				this.value = val;
    			}
    		}) // 内置的观察者模式
    
    		obj.name = "yangyang"; // 调用set
    		console.log(obj.name); // 调用get
    
    		console.log(obj.value); // yangyang
    
    		console.log(obj); // vuejs
    	</script>
    </body>
    </html>
    

    demo2.html :

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Document</title>
    </head>
    <body>
    	<div id="app">
    		<input v-model="message" />
    		<p v-model="message"></p></div>
    	</div>
    
    	<script>
    		// app 当前的模板
    		var model = { // 作为模型数据
    			// 设置message属性
    			message:"xxxxxxxxxxxxx"
    		}
    
    		// 通过当前查找 通过属性查找子元素
    		var elments = app.querySelectorAll("[v-model=message]"); // 返回一个数组的集合
    		console.log(elments.length);
    		// 遍历
    		for(var i=0;i<elments.length;i++){
    			elments[i].onkeyup = function() {
    				// 获取 this.value
    				// console.log(this.value);
    				// 将值给model.message
    				model[this.getAttribute("v-model")] = this.value;
    				console.log(model.message);
    			}
    		}
    
    		// Object.defineProperty 是 Object 的静态方法
    		Object.defineProperty(model,"message",{ // 参数:观察对象  属性名 描述对象
    			get:function(){ // 获取 阻截访问属性  钩子函数
    				// console.log("max is max");
    				// return "yangyang"
    				return this.value;
    			}, // 将钩子函数的返回值作为 访问属相的返回值(集对象的属性值)
    			set:function(val){ // 设置
    				var models = app.querySelectorAll("[v-model=message]");
    				for(var i=0;i<models.length;i++){
    					models[i].value = val;
    					models[i].innerHTML = val;
    				}
    				this.value = val;
    			}
    		}); // 内置的观察者模式
    
    		// 数据双向绑定
    		// 模板引擎
    		// 响应式原理
    		// observer模块
    		// 数据追踪
    		// 路由
    		// 状态管理
    		// 虚拟DOM
    		// 自定义指令
    		// 服务端渲染
    	</script>
    </body>
    </html>
    

    demo3.html :

    <!DOCTYPE html>
    <html lang="en">
    <head>
    	<meta charset="UTF-8">
    	<title>Document</title>
    </head>
    <body>
    	<div id="app">
    		<input v-model="message" />
    		<p v-model="message"></p>
    	</div>
    	
    	<script src="js/vue-1.1.0.js"></script>
    	<script>
    		var model = {
    			message:"",
    			data:model
    		}
    
    		var app = new Vue({
    			el:"#app", // 绑定模块DOM结构 
    			data:{
    				message:"",
    				text:""
    			}// 配置
    		})
    
    		//
    	</script>
    </body>
    </html>
    

    模仿vue

    vue-1.1.0.js :

    // 自运行函数
    (function(root,factory){ // 创建作用域  命名空间
    	// 调用工厂函数
    	root.Vue = factory(); // 返回vue 在window下扩展了vue的属性
    })(this,function(){
    	// 默认配置
    	var _DEFALUT_ = { //用户没有传值,默认优先,用户传值,配置覆盖
    		el:"body",
    		data:{}
    	}
    	var Vue = function(option){ // 构造函数
    		// console.log(this.el); // body 扩展
    		this.extend(this,_DEFALUT_,option); // 合并 this实例对象
    		this.el = document.querySelectorAll(this.el); // 转换成element对象
    		// console.log(this.el);
    		// console.log(this.data);
    
    		// 增加观察观察者模式
    		this.observer();
    
    		// 通过当前查找 通过属性查找子元素
    		var elments = this.el.querySelectorAll("[v-model]"); // 返回一个数组的集合
    		// 遍历
    		for(var i=0;i<elments.length;i++){
    			elments[i].onkeyup = function() {
    				// 获取 this.value
    				// console.log(this.value);
    				// 将值给model.message
    				model[this.getAttribute("v-model")] = this.value;
    				console.log(model.message);
    			}
    		}
    	}
    	// 创造extend,用于扩展
    	Vue.prototype = {
    		extend:function(){ // 扩展
    			// 从第二个对象开始循环
    			for(var i=1;i<arguments.length;i++){ // 2 arguments[1]
    				for(var name in arguments[i]){ // for in 循环当前对象的可枚举属性,例如name
    					// console.log(name);
    					// 开始扩展
    					this[name] = arguments[i][name]
    				}
    			}
    		},
    		observer:function(){
    			var el = this.el;
    			// let 定义块作用域
    			for(let key in this.data){
    				Object.defineProperty(this.data,key,{ // 参数:观察对象  属性名 描述对象
    					}get:function(){ // 获取 阻截访问属性  钩子函数
    						return this.value;
    					}, // 将钩子函数的返回值作为 访问属相的返回值(集对象的属性值)
    					set:function(val){ // 设置
    						console.log(key);
    						var models = el.querySelectorAll("[v-model]=" + key + "]");
    						for(var i=0;i<models.length;i++){
    							models[i].value = val
    							models[i].innerHTML = val
    						}
    						this.value = val;
    					}
    				}) // 内置的观察者模式
    			}
    		}
    	}
    
    	return Vue;
    });  // this 代表window对象 function 工厂函数  this也可以理解为根作用域
    
    // console.log(Vue); // 拿到工厂函数中定义的构造函数
    
    // 通过new方法,创建vue的实例
    

    .

  • 相关阅读:
    mySQL教程 第1章 数据库设计
    System center virtual machine manager 2008 R2安装部署及实战技术
    cisco ssh配置
    IPv6地址介绍
    远程桌面如何复制本地文件 远程桌面拷贝电脑上的文件方法
    mySQL教程 第2章 准备学习用到的表和数据
    十四个ASP.NET基础知识问答(C#版)
    十四个ASP.NET基础知识问答(C#版)
    关闭框架网页(C#)
    关闭框架网页(C#)
  • 原文地址:https://www.cnblogs.com/crazycode2/p/7084263.html
Copyright © 2011-2022 走看看