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 ...
随机推荐
- .net framework 2.0使用扩展方法
.net framework中使用扩展方法,由网摘上看到,是因为编译器将扩展方法带上了ExtensionAttribute特性 要在.net framework 2.0中使用的话,可以自定义一个特性: ...
- Easy Install详细参数
Easy Install Easy Install is a python module (easy_install) bundled with setuptools that lets you au ...
- Android控件点击事件
1. 介绍 本文介绍了Android控件的点击事件 Android控件点击(onClick)事件可以用如下三种方式来实现 2. 实现onClick方法 在layout的xml中指定onClick方法, ...
- 或许你不知道的10条SQL
一.一些常见的SQL实践 (1)负向条件查询不能使用索引 select * from order where status!=0 and stauts!=1 not in/not exists都不是好 ...
- Laravel中ajax添加CsrfToken的方法
//在模板文件的header头中添加 <meta name="_token" content="{{ csrf_token() }}"/> //aj ...
- 网易 监控 openstack
http://www.360doc.com/content/16/0416/08/13792507_551022987.shtml
- (1)OracleClient数据库操作(淘汰)
一.数据库连接 Oracle 数据提供程序,位于System.Data.OracleClient 命名空间.( .NET 4 以后的版本,会将不在维护和更新了) 第一步:引入命名空间 在程序的开头写上 ...
- NYOJ 71 乘船问题【贪心】
时间复杂度O(n) 有n个人,第i个人的重量为w[i],每艘船的最大载重量均为c,且最多只能乘两个人.用最少的船装载所有人. 思路:从最轻的开始考虑,让最轻的和最重的一条船,若超出重量则可判定最重的只 ...
- hihocoder Arithmetic Expression【在线查询】
Arithmetic Expression 时间限制:2000ms 单点时限:200ms 内存限制:256MB 描述 Given N arithmetic expressions, can you ...
- 大数据技术之_16_Scala学习_08_数据结构(下)-集合操作+模式匹配
第十一章 数据结构(下)-集合操作11.1 集合元素的映射-map11.1.1 map 映射函数的操作11.1.2 高阶函数基本使用案例1+案例211.1.3 使用 map 映射函数来解决11.1.4 ...