常见的架构设计模式有MVC、MVP、MVVM。三者的共同点在于MV,既Model模型层和View视图层,模型层主要是业务逻辑相关的数据以及数据的处理,视图层主要是负责将数据渲染到页面上,展示给用户。那不同点在哪里。
一、MVC架构模式
MVC的C是controller,即控制层,负责响应用户的输入的业务逻辑,MVC的通信是单向循环的。模型层将数据给到试图成进行展示,视图成将用户的输入交给控制层进行业务处理,控制层调用模型层相关数据的处理,模型成将新数据给到视图层展示。这就是MVC的事件处理流程。
二、MVP架构模式
MVP的P是Presenter,可以理解为是中间人,它移除了MVC中视图层和模型层的直接交互,两者通过Presenter来进行交互。Presenter获取模型层的数据渲染至视图层,响应处理用户在视图层的输入行为,修改模型层数据,然后再将新数据渲染至视图层。
三、MVVM架构模式
现在讲讲这篇文章的重点MVVM,VM即view model,基本上与MVP模式类似,区别在于vm是通过双向数据绑定来实现视图与模型的自动同步的。现在流行的vue框架底层架构模式就是MVVM。VM主要分为两个部分,一部分是DOMListener,响应处理用户对view的一些交互事件,然后处理响应的model层数据; 还有一部分是DataBinding,就是将model里的数据与view中的对应元素进行绑定,实现数据的展示。这两部分就是MVVM中的双向数据绑定,在vue中实现这两个部分主要通过数据挟持和发布者订阅者模式。
3.1数据挟持
数据挟持就是挟持数据的操作,在对数据进行修改或者获取等操作的时候可以执行额外的业务逻辑。vue2的数据挟持采用的是Object.defineProperty来进行数据的挟持,现在的vue3采用了Proxy代理来实现数据的挟持。
以下演示了通过Object.defineProperty进行数据的挟持:
class MyVue{
constructor({
data}){
this.hijack(data)
}
hijack(data){
Object.keys(data).forEach(key=>{
Object.defineProperty(this,key,{
get(){
console.log(`get${
key}`)
return data[key]
},
set(newValue){
console.log(`set${
key}`)
data[key]=newValue;
}
})
})
}
}
let data={
name:'zhangsan',
age:11,
list:[1,2,3,4]
}
let vue=new MyVue({
data})
vue.name='lisi';
console.log(vue.name)
以下演示了用proxy来实现数据挟持:
class MyVue{
constructor({
data}){
this.hijack(data)
}
hijack(data){
this.data=new Proxy(data,{
get:function(target,key){
console.log(`get${
key}`)
return target[key];
},
set:function(target,key,newValue){
console.