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的实例

.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程介绍本套课程,大喵将带着大家,编辑每一行代码,使用原生Javascipt及ES6的一些新特性,仿照目前国内非常流行的Vue框架的码,开发构建一个属于你们自己的MVVM框架。让大家能够很清晰的学习及掌握,模板编译,数据绑定,响应式,文档碎片,观察者模式,发布订阅模式等等,这些Vue的核心知识点,都是怎么回事,它们之间有哪些关联,是如何进行双向数据绑定的等等。在使用vue2.x的核心Object.defineProperty构建完成框架后,大喵也会使用Vue3.0引入的数据劫持的Proxy新特性,来改造我们的MVVM框架,提升我们的框架性能。最终,大喵会带着大家,从0开始配置webpack.config.js配置文件以及引入babel-loader,配置.babelrc文件,转换我们JS文件中的的ES6语法,最终压缩输出我们的MVVM框架库文件。课程目录01 搭建MVVM框架 课程介绍、02 文件结构及基础类创建、03 入口类DamiaoMvvm的实、04 模板编译、05 元素节点解析编译、06 v-model 数据绑定逻辑梳理、07 v-model 数据绑定实、08 模板文本编译逻辑梳理、09 模板文本渲染绑定、10 观察者Wather逻辑梳理、11 Wather 逻辑实、12 Object.defineProperty()、13 defineProperty 小案例、14 observer数据劫持梳理、15 defineProperty数据劫持实、16 发布订阅类实、17 Proxy 介绍与概述、18 使用Proxy改造MVVM框架、19 使用Proxy实响应式、20 webpack 打包配置、21 babel 配置及文件输出、22 Mvvm Proxy 框架打包、23 Mvvm 框架搭建课程总结MVVM框架介绍MVVM是 Model-View-ViewModel 的缩写。mvvm是一种设计思想。Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展出来,ViewModel 是一个同步View 和 Model的对象。在MVVM架构模式下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值