MVVM的理解
概念:MVVM是一种架构模式(设计模式),它是
Model
,View
,ViewModel
的首字母简写
Model
:数据层,提供数据View
:视图层,渲染页面,响应页面的交互行为ViewModel
:视图模型层,它是数据层和视图层交互数据的桥梁(连接数据层和视图层的桥梁)
MVVM的核心
- MVVM的核心:实现了数据的双向绑定,数据驱动视图,当数据发生改变时,会自动更新视图,不需要再操作DOM节点,当视图中的数据发生改变时,会自动更新数据
为了便于理解MVVM的核心思想
- 下面使用ES5的
Object.defineProperty()
实现MVVM的架构模式
Object.defineProperty()
:实现数据劫持,只能监听对象中的一个属性
语法:
Object.defineProperty(劫持的对象,'监听的属性',{
get:function(){
//访问被监听的属性时触发
},
set:function(){
//修改被监听的属性时触发
}
})
代码实现:
//数据层,提供数据
let model = {
uname:"李云龙"
}
//视图模型层,连接数据层和视图层的桥梁
//必须要用到数据劫持,来监听属性
let _uname = model.uname
Object.defineProperty(model,'uname',{
get:function(){
//访问被监听的uname属性时触发
console.log('访问了被监听的属性', new Date())
//这里如果返回的是被监听的属性,那么就会变成死循环,只要访问了被监听的属性,就会一直触发get方法
return _uname
},
set:function(newVal){
//修改被监听的uname属性的值时触发
console.log('修改了被监听的属性',new Date(),newVal)
//修改视图层的数据
_uname = newVal
//通知视图层更新,MVVM的核心就是通过数据绑定,通过视图模型层来连接视图层和数据层
//它不能直接去修改属性的值,而应该是通知的方式去让视图层修改数据
watch()
}
})
//视图层,渲染页面,响应交互行为
function render(){
app.innerHTML = `<span>${model.uname}</span><button οnclick="changeUname()">点击</button>`
}
render()
function changeUname(){
model.uname = '孔捷'
}
function watch() {
render()
}
在VSCode中编译执行
点击后
在console中可以看到访问后触发了get函数,在点击修改监听的“uname”属性时,触发了set函数和get函数
下面使用ES6的proxy来实现MVVM架构模式
Proxy
实现数据代理,可以代理整个对象
- 语法:
let 实例对象 = new Proxy(代理的对象,{
get:function(target,key){
//target:被监听的对象
//key:对象的属性
//访问了被监听的对象时触发
},
set:fucntion(target,key,newVal){
//target:被监听的对象
//key:对象的属性
//newVal:修改后新的属性值
//修改了被监听的属性后触发
}
})
代码实现:
//数据层,提供数据
let model = {
uname:'楚云飞',
age:28
}
//视图模型层,连接数据层和模型层的桥梁
let newModel = new Proxy(model,{
get:function(target,key){
//访问了被监听属性时触发
console.log('访问了被监听的对象',model)
return target[key]
},
set:function(target,key,newVal){
//修改了被监听的属性时触发
console.log('修改了被监听的属性时触发')
target[key] = newVal
//通知视图更新
watch()
}
})
//视图层
function render() {
app.innerHTML = `
<span>${newModel.uname}</span><span>${newModel.age}</span>
<button οnclick="changeUname()">提交</button>
`
}
render()
function changeUname() {
newModel.uname = '云飞',
newModel.age = 78
}
function watch() {
render()
}
在VSCode中编译运行
点击了提交按钮后
可以看到在修改被监听的属性时,触发了get函数和set函数,通过proxy数据代理,实现了MVVM架构模式的思想,数据驱动视图,当数据发生改变时,通过视图模型层来沟通视图层和模型层的数据变化,在变化时通知更改数据,这样的好除是不需要在获取DOM元素节点,可以大大提高开发的效率
- ES5的
Object.defineProperty()
和ES6Proxy
的区别
ES6
的Proxy
相对于ES5
的Object.defineProperty()
来说,Proxy
它可以监听整个对象的改变,Object.defineProperty
只能监听对象中某一个属性的改变