前面几节都是jquery界面方面的东西,本节研究些数据方面的东西:MVVM。

MVVM由三部分组成:Model <=> ViewModel <=> View,当Model数据改变时,通知所有与Model关联的View进行数据更新。

以vuejs一个简单例子实现为例:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例</title>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<p>{{ message }}</p>
</div> <script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
}
})
</script>
</body>
</html>

显示效果如下

现在模拟实现这一过程,ES5,6语法以前也没怎么接触,在网上翻看大神的资料,看到一篇实现相对较完整的
https://segmentfault.com/a/1190000016236834

根据他的实现原理本文进行了简化,只模拟实现绑定过程(不能拿来用于生产环境),稍微有点javascript基础的应该都能看懂。下次面试时面试官问你原理你说可以手写一个。

网上许多文章都是观察者,订阅者一堆名词,把读者都看晕了,其实核心代码就像下面这段代码这么简单.

<body>
<div id="app">
<p>{{ message }}</p>
<p>{{ message1 }}</p>
</div>
<div id="log"></div>
<script>
class JMVVM {
constructor(p_obj) {
this.init(p_obj);
}
init(p_obj) {
$("#log").append("获取绑定对象初始化数据信息</br>");
this.element = document.querySelector(p_obj.el);
this.data = p_obj.data;
$("#log").append("el:" + this.element.id + "</br>");
for (let key in this.data) {
let val = this.data[key];
$("#log").append("key:" + key + "</br>");
$("#log").append("1、给对象创建get,set方法</br>");
let element=this.element;
Object.defineProperty(this.data, key, {
configurable: true,
enumerable: true,
get() {
return val;
},
set(newVal) {
val = newVal;
let reg = eval("/{{([^}]*) "+key+" }}/g");
// let reg1 = /{{([^}]*) +key+ }}/g;
let match;
$("#log").append("2、替换模板</br>");//模拟,只查找一级。
element.childNodes.forEach(childNode=>{
while ((match = reg.exec(childNode.textContent))) {
childNode.textContent=val;
}
})
// $("#log").append("2、替换模板</br>");
// for(let children in element.childNodes)
// while ((match = reg.exec(children.textContent))) {
// children.textContent=val;
// } }
});
       //触发set
this.data[key] =val;
} }
}
</script>
<script>
// new Vue({
// el: "#app",
// data: {
// message: "Hello Vue.js!"
// }
// });
new JMVVM({
el: "#app",
data: {
message1: "Hello JMVVM.js!"
}
});
</script>
</body>

执行结果如下

上面写法比较简单,只能替换一次,因为替换后{{ message }}就不存在了,那么就应该在第一次替换成功时候将对应元素缓存下来,具体怎么实现有多种方法,如果理解的不对,欢迎大家指正。

演示地址:www.jgui.com

注释:

ES6 新增了let命令,用来声明局部变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效,而且有暂时性死区的约束。

后续:ES6对IE兼容性挺差的,如果是客户习惯使用低版本IE的话,尽量不要使用ES6或者让客户更换浏览器。

JGUI源码:实现简单MVVM单项绑定学习笔记(15)的更多相关文章

  1. jQuery源码分析_工具方法(学习笔记)

    expando:生成唯一JQ字符串(内部使用) noConflict():防止冲突 isReady:DOM是否加载完成(内部) readyWait:等待多少文件的计数器(内部) holdReady() ...

  2. zepto源码--核心方法(类数组相关)--学习笔记

    从这篇起,在没有介绍到各类插件之前,后面将陆续介绍zepto对外暴露的核心方法.即$.fn={}里面的所有方法的介绍.会配合zepto的API进行介绍. 其实前面已经介绍了几个,如width,heig ...

  3. JGUI源码:从头开始,建一个自己的UI框架(1)

    开篇 1.JGUI是为了逼迫自己研究底层点的前端技术而做的框架,之前对web底层实现一直没有深入研究,有了技术瓶颈,痛定思痛从头研究, 2.虽然现在vue技术比较火,但还在发展阶段,暂时先使用JQue ...

  4. Vue源码解析---数据的双向绑定

    本文主要抽离Vue源码中数据双向绑定的核心代码,解析Vue是如何实现数据的双向绑定 核心思想是ES5的Object.defineProperty()和发布-订阅模式 整体结构 改造Vue实例中的dat ...

  5. JGUI源码:鼠标中键滚动再次优化(5)

    //电脑端中键滚动事件 var mousewheel = getBrowserInfo() == "Firefox" ? "DOMMouseScroll" : ...

  6. 路由其实也可以很简单-------Asp.net WebAPI学习笔记(一) ASP.NET WebApi技术从入门到实战演练 C#面向服务WebService从入门到精通 DataTable与List<T>相互转换

    路由其实也可以很简单-------Asp.net WebAPI学习笔记(一)   MVC也好,WebAPI也好,据我所知,有部分人是因为复杂的路由,而不想去学的.曾经见过一位程序猿,在他MVC程序中, ...

  7. 从源码来理解slf4j的绑定,以及logback对配置文件的加载

    项目中的日志系统使用的是slf4j + logback.slf4j作为一个简单日志门面,为各种loging APIs(像java.util.logging, logback, log4j)提供一个简单 ...

  8. JGUI源码:Accordion鼠标中键滚动和手机端滑动实现(2)

    本文是抽屉组件在PC端滚动鼠标中键.手机端滑动时,滚动数据列表实现方法,没有使用iscroll等第三方插件,支持火狐,谷歌,IE8+等浏览器. 演示在:www.jgui.com Github地址:ht ...

  9. (二十三)原型模式详解(clone方法源码的简单剖析)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 原型模式算是JAVA中最简单 ...

随机推荐

  1. go语言框架gin之集成swagger

    1.安装swag 在goLand中直接使用go get -u github.com/swaggo/swag/cmd/swag命令安装会报错 翻了很多博客,都没找到太合适的办法,根据博客中所写的操作还是 ...

  2. Django的URL调度

    1.URLconf (URL configuration):(Django版本1.11.20,其它版本可能各有差异.) 在Django中Python后端与前端URL进行交互,是通过一个名为urlcon ...

  3. Python Learning: 02

    OK, let's continue. Conditional Judgments and Loop if if-else if-elif-else while for break continue ...

  4. js坚持不懈之14:不要在文档加载之后使用 document.write()示例

    在看w3school的JavaScript教程时,关于文档输出流中有这么一句话:绝不要在文档加载之后使用 document.write().这会覆盖该文档. 不太明白什么意思,找了一个例子: < ...

  5. 小程序--scroll-view的横向滑动无效

  6. 类System

    System类简介: 在 System 类中提供了大量的静态方法,有标准输入.标准输出和错误输出流:对外部定义的属性和环境变量的访问:加载文件和库的方法:还有快速复制数组的一部分的实用方法. 常用方法 ...

  7. Nonlinear Component Analysis as a Kernel Eigenvalue Problem

    目录 引 kernel PCA kernel 的选择 性质 一些问题 代码 Scholkopf B, Smola A J, Muller K, et al. Nonlinear component a ...

  8. scala的多种集合的使用(6)之映射Map的操作方法

    1.创建映射 1)创建不可变的映射 scala> val status = Map(1 -> "a",2 -> "b") status: sc ...

  9. Python类和对象

    目录 类与对象 其他方法 继承 经典类和新式类 派生 组合 接口.归一化设计与抽象类 继承实现的原理 子类中调用父类的方法 指名道姓 super()方法 多态与多态性 封装 单下划线开头 双下划线开头 ...

  10. MR 实例

    二次排序 点击复制代码:https://www.cnblogs.com/JBLi/p/10764535.html 将上面的代码改成两个 分区    展示的数据 相同的不在一个分区 怎么解决点击查看没有 ...