Vue的mvvm
MVVM,M数据,V视图,VM数据绑定,可以算的上是一种创新。简单来说,数据的双向绑定其实可以说是在单向的基础上加一个监听
- 三者与vue的关系
view 对应 template,vm 对应 new Vue({…}),model 对应 data
- 三者的关系
view 可以通过事件绑定的方式影响 model,model 可以通过数据绑定的形式影响到view,viewModel是把 model 和
view 连起来的连接器
所以在这里我们也可以自定义类似vue框架constructor 是一种用于创建和初始化class创建的对象的特殊方法。 在一个类中只能有一个名为 “constructor”
的特殊方法
- Vue 如何实现响应式
这里的响应式是指修改了data属性之后,vue立刻监听到,立刻去渲染页面。data属性被代理到vm上面。在这里主要通过Object.defineProperty去实现相应式,去进行数据劫持。
- vue的MVVM的实现。MVVM的主要涉及思想有观察者模式,发布-订阅者模式
对模板进行编译,解析,将vue的指令编译为html语言,同时订阅数据变化,绑定更新函数,在数据劫持中发现有数据改变的时候,就会告诉dep数据改变。Dep就会通知watcher进行update,回调,compile中就会将数据替换,更新到视图上
// 先创建一个MVue类,它是一个入口
Class MVue {
constructor(options) { }
if(this.$el) {
// 1.实现一个数据的观察者 --先看解析器,再看Obeserver
new Observer(this.$data)
// 2.实现一个指令解析器
new Compile(this.$el,this)
}
}
// 定义一个Compile类解析元素节点和指令
Class Compile {}
// 定义一个对象,针对不同指令执行不同操作
const compileUtil = {
// 解析参数(包含嵌套参数解析),获取其对应的值
getVal(expre, vm) { },
// 获取当前节点内参数对应的值
getgetContentVal(expre,vm) { },
// 设置新值
setVal(expre, vm, inputVal) { },
// 指令解析:v-test
test(node, expre, vm) {
let value;
if(expre.indexOf('{{') !== -1) {
// 正则匹配{{}}里的内容
value = expre.replace(/\{\{(.+?)\}\}/g, (...arges) => { // new watcher这里相关的先可以不看,等后面讲解写到观察者再回头看。这里是绑定观察者实现的效果是通过改变数据会触发视图,即数据=》视图。没有new watcher 不影响视图初始化(页面参数的替换渲染)。
// 订阅数据变化,绑定更新函数。
new watcher(vm, arges[1], () => {
// 确保 {{person.name}}----{{person.fav}} 不会因为一个参数变化都被成新值
this.updater.textUpdater(node, this.getgetContentVal(expre,vm))
})
return this.getVal(arges[1],vm)
})
} else {
// 数据=》视图
new watcher(vm, expre, (newVal) => { // 找不到{}说明是test指令,所以当前节点只有一个参数变化,直接用回调函数传入的新值
this.updater.textUpdater(node, newVal)
})
value = this.getVal(expre,vm)
}
// 将数据替换,更新到视图上
this.updater.textUpdater(node,value)
},
//指令解析: v-html
html(node, expre, vm) { },
// 指令解析: v-on
on(node, expre, vm, eventName) { }
// updater对象,管理不同指令对应的更新方法
updater: { }
// 定义一个观察者
class watcher {
Constructor(){}
getOldVal() {}
update() {}
}
// 定义一个观察者集合
class Dep {
constructor() {}
addSub(watcher) {
this.subs.push(watcher)
}
notify() {
this.subs.forEach(w => w.update())
}
}
// 定义一个Observer类通过gettr,setter实现数据的监听绑定
class Observer {
constructor(data) {
this.observer(data)
}
// 定义函数解析data,实现数据劫持
observer (data) { }
// 数据劫持方法
defineReactive(obj,key, value) {
// 递归遍历
this.observer(data)
// 实例化一个dep对象
const dep = new Dep()
// 通过ES5的API实现数据劫持
Object.defineProperty(obj, key, {
enumerable: true,
configurable: false,
get() {
// 当读当前值的时候,会触发。
// 订阅数据变化时,往Dep中添加观察者
Dep.target && dep.addSub(Dep.target)
return value
},
set: (newValue) => {
// 对新数据进行劫持监听
this.observer(newValue)
if(newValue !== value) {
value = newValue
}
// 告诉dep通知变化
dep.notify()
}
})
}
}