前面几节都是jquery界面方面的东西,本节研究些数据方面的东西:MVVM。javascript
MVVM由三部分组成:Model <=> ViewModel <=> View,当Model数据改变时,通知全部与Model关联的View进行数据更新。html
以vuejs一个简单例子实现为例:vue
<!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>
显示效果以下java
如今模拟实现这一过程,ES5,6语法之前也没怎么接触,在网上翻看大神的资料,看到一篇实现相对较完整的
https://segmentfault.com/a/1190000016236834jquery
根据他的实现原理本文进行了简化,只模拟实现绑定过程(不能拿来用于生产环境),稍微有点javascript基础的应该都能看懂。下次面试时面试官问你原理你说能够手写一个。面试
网上许多文章都是观察者,订阅者一堆名词,把读者都看晕了,其实核心代码就像下面这段代码这么简单.segmentfault
<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("一、给对象建立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("二、替换模板</br>");//模拟,只查找一级。 element.childNodes.forEach(childNode=>{ while ((match = reg.exec(childNode.textContent))) { childNode.textContent=val; } }) // $("#log").append("二、替换模板</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.comapp
注释:
ES6 新增了let
命令,用来声明局部变量。它的用法相似于var
,可是所声明的变量,只在let
命令所在的代码块内有效,并且有暂时性死区的约束。
后续:ES6对IE兼容性挺差的,若是是客户习惯使用低版本IE的话,尽可能不要使用ES6或者让客户更换浏览器。