JGUI源码:实现简单MVVM单项绑定学习笔记(15)

时间:2023-03-10 01:23:43
JGUI源码:实现简单MVVM单项绑定学习笔记(15)

前面几节都是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>

显示效果如下
JGUI源码:实现简单MVVM单项绑定学习笔记(15)

现在模拟实现这一过程,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>

执行结果如下
JGUI源码:实现简单MVVM单项绑定学习笔记(15)

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

演示地址:www.jgui.com

注释:

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

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