MVVM是Model-View-ViewModel的简写。它本质上就是MVC 的改进版。MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开。当然这些事 ViewModel 已经帮我们做了,它可以取出 Model 的数据同时帮忙处理 View 中由于需要展示内容而涉及的业务逻辑。vue中采用的数据劫持+ 发布者订阅者模式
https://blog.csdn.net/dwfrost/article/details/85777900
1.要用到的基本属性属性--用法自己可以参考api
Object.defineProperty(obj,'name',{
configurable:true,
//writable:true,
enumerable:false,
// value: 'zpc',
get(){
return 'zpc'
},
set(val){
console.log(val)
},
})
2.简单对象模拟observe实现数据劫持--实现对象的监视赋值
代码示例---还有如果对象内部属性还是对象的话就要循环监听
var a = new Wrapper({ // 模拟new vue 构造示例对象
el:'#app',
data:{
a:1
}
})
function Wrapper (options={}){ // 定义构造函数,并进行参数绑定传递
this.$option = options
var data = this._data = option.data
observe(data)
}
function observe(data){
return new Observe(data)
}
function Observe(data){ // 定义Observe 构造函数,进行属性描述符设定监听赋值
for (let key in data) {
var val = data[key]
Object.defineProperty(data,key,{
configurable:true,
enumerable:true,
get(){
return val
},
set(newval){
if(newval == val){
return
} else {
val = newval
}
},
})
}
}
此时打印console.log(a)
输出
{
_data{a:1}
}
但是此时要的不是这个效果,是需要直接把a挂载在this上---需要实现数据代理
3.模拟实现数据代理
在上边的构造 函数实现数据劫持之后 添加数据代理
function Wrapper (options={}){ // 定义构造函数,并进行参数绑定传递
this.$option = options
var data = this._data = option.data
observe(data) // 实现数据监视
=======================新添加=================================
for (let key in data) { // 循环对象实现数据代理
var val = data[key]
Object.defineProperty(this,key,{
configurable:true,
enumerable:true,
get(){
return this._data[key] // 此处就是相当于赋值操作this.a = this._data[key]
},
set(newval){
this._data[key] = newval
},
})
}
========================新添加=========================================
}
1.vue的特点是不能新添加不存在的属性,不存在的属性没有set get 方法
2.深度监视的原来,就是每次赋值内部对象添加数据代理和数据劫持
4.发布订阅模式--代码实现
发布订阅
function Dep (){
this.subs = []
}
Dep.prototype.addSub = function(sub){
this.subs.push(sub)
}
Dep.prototype.nitify = function(){
this.subs.forEach(
sub=>sub.update()
)
}
实现watcher
function Watcher(fn){
this.fn = fn
}
Watcher.prototype.update = function(){
this.fn()
}
代码执行流程
let watcher = new Watcher(function(){
console.logI('1')
})
let dep = new Dep()
dep.addSub(watcher)
dep.notify() -将函数依次执行