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的实例
.
MVVM模式源码分析手写实现的更多相关文章
- 面试必会之ArrayList源码分析&手写ArrayList
简介 ArrayList是我们开发中非常常用的数据存储容器之一,其底层是数组实现的,我们可以在集合中存储任意类型的数据,ArrayList是线程不安全的,非常适合用于对元素进行查找,效率非常高. 线程 ...
- 源码分析 | 手写mybait-spring核心功能(干货好文一次学会工厂bean、类代理、bean注册的使用)
作者:小傅哥 博客:https://bugstack.cn - 汇总系列原创专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言介绍 一个知识点的学习过程基本分为:运行helloworld ...
- Spring源码分析 手写简单IOC容器
Spring的两大特性就是IOC和AOP. IOC Container,控制反转容器,通过读取配置文件或注解,将对象封装成Bean存入IOC容器待用,程序需要时再从容器中取,实现控制权由程序员向程序的 ...
- 并发编程学习笔记(9)----AQS的共享模式源码分析及CountDownLatch使用及原理
1. AQS共享模式 前面已经说过了AQS的原理及独享模式的源码分析,今天就来学习共享模式下的AQS的几个接口的源码. 首先还是从顶级接口acquireShared()方法入手: public fin ...
- springMVC源码分析--HttpMessageConverter写write操作(三)
上一篇博客springMVC源码分析--HttpMessageConverter参数read操作中我们已经简单介绍了参数值转换的read操作,接下来我们介绍一下返回值的处理操作.同样返回值的操作操作也 ...
- 【一起学源码-微服务】Nexflix Eureka 源码十二:EurekaServer集群模式源码分析
前言 前情回顾 上一讲看了Eureka 注册中心的自我保护机制,以及里面提到的bug问题. 哈哈 转眼间都2020年了,这个系列的文章从12.17 一直写到现在,也是不容易哈,每天持续不断学习,输出博 ...
- Android Doze模式源码分析
科技的仿生学无处不在,给予我们启发.为了延长电池是使用寿命,google从蛇的冬眠中得到体会,那就是在某种情况下也让手机进入类冬眠的情况,从而引入了今天的主题,Doze模式,Doze中文是打盹儿,打盹 ...
- Spring源码 20 手写模拟源码
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- 《四 spring源码》手写springmvc
手写SpringMVC思路 1.web.xml加载 为了读取web.xml中的配置,我们用到ServletConfig这个类,它代表当前Servlet在web.xml中的配置信息.通过web.xml ...
随机推荐
- penGL入门学习(六)
http://blog.csdn.net/sun6255028/article/details/5090067 今天要讲的是动画制作——可能是各位都很喜欢的.除了讲授知识外,我们还会让昨天那个“太阳. ...
- Delphi实现截屏存盘的方法
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...
- win2008通过计划任务定时执行bat文件
前段时间在Windows Server 2008安装了一套基于MySQL数据库的软件,处于数据安全的考虑,希望每天能够自动进行数据库备份.我在别人脚本的基础上自己写了一个数据库备份的bat脚本,双击该 ...
- 大数据技术之_16_Scala学习_09_函数式编程-高级
第十三章 函数式编程-高级13.1 偏函数(partial function)13.1.1 提出一个需求,引出思考13.1.2 解决方式-filter + map 返回新的集合13.1.3 解决方式- ...
- HDU 1024 Max Sum Plus Plus(基础dp)
Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- 洛谷——P1991 无线通讯网
P1991 无线通讯网 题目描述 国防部计划用无线网络连接若干个边防哨所.2 种不同的通讯技术用来搭建无线网络: 每个边防哨所都要配备无线电收发器:有一些哨所还可以增配卫星电话. 任意两个配备了一条卫 ...
- POJ 1274 The Perfect Stall (二分图匹配)
[题目链接] http://poj.org/problem?id=1274 [题目大意] 给出一些奶牛和他们喜欢的草棚,一个草棚只能待一只奶牛, 问最多可以满足几头奶牛 [题解] 奶牛和喜欢的草棚连线 ...
- Nginx的server为0.0.0.0/0.0.0.1的作用?
看到kong默认的代理和后台server 都是0.0.0.0,代理到上游的服务器proxy_pass $upstream_scheme://kong_upstream;配置如下, upstream k ...
- 十. 图形界面(GUI)设计3.标签、按钮和按钮事件
标签和按钮也许是图形界面中最常见的两种组件,按钮又总是与激发动作事件有关. 标签 标签(JLabel)是最简单的Swing组件.标签对象的作用是对位于其后的界面组件作说明.可以设置标签的属性,即前景色 ...
- [bug]The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
写在前面 在模拟请求的时候,如果url为https的,会报这个错误.大概错误就是:基础连接已关闭:无法建立信任关系的SSL / TLS的安全通道. The underlying connection ...