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 ...
随机推荐
- vue-cli打包后图片路径取不到的问题
今天准备把vue-cli build 的文件发到服务器上单发现会出现图片找不到的问题 解决办法如下 修改 assetsPublicPath: './' .打开webpack.prod.conf.js, ...
- Educational Codeforces Round 32
http://codeforces.com/contest/888 A Local Extrema[水] [题意]:计算极值点个数 [分析]:除了第一个最后一个外,遇到极值点ans++,包括极大和极小 ...
- Best Time to Buy and Sell Stock with Cooldown -- LeetCode
Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...
- iOS静态库打包
当了三年多程序员,第一次写随便,说来有些惭愧.想成为一个优秀的程序员,分析,思考,总结并且做记录是必不可少的,今天先从简单的命令总结记起.好了,废话不多说了,Let's start our games ...
- MySQL四种类型日志:Error Log、General Query Log、Binary Log、Slow Query Log
MySQL Server 有四种类型的日志——Error Log.General Query Log.Binary Log 和 Slow Query Log. 第一个是错误日志,记录mysqld的一些 ...
- Vue 基础的开发环境
本期节目将手把手教你去 NPM 市场买最新鲜的食材,只为搭配 小鲜肉 Vue 下厨. 既然它是当红小鲜肉,我想有必要写一篇文章来帮助大家配置好 Vue 的生产环境,我给它的总体评价是“简单却不失优雅, ...
- FIREDAC记录SQL日志
FIREDAC记录SQL日志 跟踪SQL日志可以方便开发的时候的程序调试.SQL日志记录会耗费服务费资源,正式部署中间件的时候,建议关闭SQL日志记录. FIREDAC通过使用TFDMoniFlatF ...
- DoTween 部分中文文档
前言 DOTween现在还处于 alpha,所以还有一些缺失的功能(如路径插件,附加回调和其它的tween选项),这个文档在不久的将来可能会改变. 一.术语 Tweener 一个tween控制valu ...
- 使用ajax,结合jquery,php实现图片上传预览功能
大致逻辑:点击页面的file,上传图片到指定的php处理图片的文件,处理完成以后,将图片的连接地址返回,JS控制返回的数据,然后将图片动态的展示出来html代码<label> <im ...
- LNMP第一部分环境搭建
1. MySQL安装(同LAMP里面的安装方法)2. php安装wget http://cn2.php.net/distributions/php-5.4.37.tar.bz2tar jxf ph ...