MVVM(Model-View-ViewModel)是在MVC(Model-View-Control)模式之后引出的新的开发模式,他与MVC
模式一样用于把视图(界面)和数据进行解耦,不同的是采用ViewModel来完成数据与视图的双向绑定,通
过自动化的方式承担大部分数据工作,来解决由于界面复杂化和快速迭代带来的问题。
由于现在vue比较火,现在就用vue相同的原理(属性劫持)来完成一个简单MVVM框架
创建dom
var html="{{msg}}{{msg2}}
{{msg}}
";
var div = document.createElement("div");
div.id="app";
div.innerHTML = html;
document.body.appendChild(div);
数据对象(Model),与dom绑定的数据都在这儿
var Model = {
msg:"hello world",
msg2:"hello world2"
};
视图对象(View),里面封装了对dom节点的解析、事件绑定、视图更新渲染等方法
var View = {
init:function(el){
//将数据与View绑定
ViewModel.bind(Model);
//解析Dom
this.processNode(el);
},
subs:[],
processNode:function(el){
var node = document.querySelector(el);
var frag = document.createDocumentFragment(),child;
while(child = node.firstChild){
this.compile(child);
frag.appendChild(child);
}
node.appendChild(frag);
},
compile:function(node){
function Sub(node,name,nodeType){
this.node = node;
this.name = name;
this.nodeType = nodeType;
}
var self = this;
if(node.nodeType === 1){
if(node.childNodes){
var nodes =[...node.childNodes];
nodes.forEach(function(node){
self.compile(node);
})
}
var attrs = [...node.attributes];
attrs.forEach(function(attr){
if(attr.nodeName === "v-model"){
var name = attr.nodeValue;
node.addEventListener("input",function(e){
self[name] = e.target.value;
});
node.value = self[name];
node.removeAttribute("v-model");
var sub = new Sub(node,name,"input");
self.render(sub);
self.subs.push(sub);
}
})
}
if(node.nodeType === 3){
if(/{{(.*)}}/.test(node.nodeValue)){
var name = RegExp.$1;
name=name.trim();
var sub = new Sub(node,name,"text");
self.render(sub);
self.subs.push(sub);
}
}
},
update:function(){
var self = this;
this.subs.forEach(function(sub){
self.render(sub);
})
},
render:function(sub){
if(sub.nodeType === "input"){
sub.node.value=this[sub.name];
}
if(sub.nodeType === "text"){
sub.node.nodeValue=this[sub.name];
}
}
};
视图模板绑定对象(ViewModel),这也是mvvm实现的核心方法,通过defineProperty将Model对象中的数据
复制到了View对象中,并对数据进行了监控,每当get或set时都会触发自定义事件,完成对视图的跟新。
var ViewModel={
bind:function(m){
Object.keys(m).forEach(function(key){
Object.defineProperty(View,key,{
get:function(){
return m[key];
},
set:function(newVal){
m[key] = newVal;
this.update();
}
})
});
}
};
最后调用View对象的初始化方法执行框架,至此就完成了一个简单的MVVM框架。
View.init("#app");
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/94727.html
摘要:它由微软架构师和开发,通过利用微软图形系统和的互联网应用派生品的特性来简化用户界面的事件驱动程序设计。微软的和架构师之一于年在他的博客上发表了。更改时会得到提醒这个情况是一个单向流。 前言 记得四个月前有一次面试,面试官问我 MVVM 是什么,MVVM 的本质是什么。我大脑一片混乱,那时我对 MVVM 的认知就只是双向绑定和Vue,以这个关键字简单回答了几句,我反问 MVVM 的本质是...
阅读 2226·2021-11-24 09:39
阅读 1162·2021-09-30 09:48
阅读 1265·2021-09-22 15:29
阅读 2639·2019-08-30 14:17
阅读 2063·2019-08-30 13:50
阅读 1603·2019-08-30 13:47
阅读 1201·2019-08-30 13:19
阅读 3642·2019-08-29 16:43