Vue中的MVVM原理,以及双向数据绑定的理解
MVVM原理:
响应式,双向数据绑定,即MVVM。
M : model(数据) V:View(视图) VM(视图数据)
实际上,model和视图不能直接通信,需要通过vm进行数据传递,vm中有一个观察者,当model中数据发生改变以后,会通知视图进行对应的视图更新,当视图发生改变,vm也能监听到视图的变化,通过元素的DOM事件进行监听视图是否发生改变,如果改变,通知数据进行更改;
通过代码进行简单的理解
<body>
<div id="app">
{{msg}}
<input type="text" v-model="msg">
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
// 这个属性会被观察者监听,当发生变化后,会更新视图;
msg:"hello"
}
});
vm.msg="world";//数据=>视图 当data中的数据发生改变,视图也会发生更新;
//视图=>数据 输入改变input框中的值,会让data中的数据同时发生改变
// MVC : model view controller
</script>
</body>
打开页面后是这样的
更改input框后视图也会跟着改变
双向数据绑定的理解
双向数据绑定:数据能影响视图 视图影响数据;
1. 简单可以这么理解
vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
简单的理解一下Object.defineProperty()这个属性
let obj = {name:88,age:99};
Object.defineProperty(obj,"name",{
get(){
// 当获取obj对应name属性对应的属性值时,会默认执行这个get方法
console.log(100);
// get方法的return返回值就是该属性名对应的属性值
//return 1;
},
set(b){
// 当设置obj的name属性值时,会默认执行set方法;
// 这个形参就接收到了设置属性名的属性值;
console.log(b);
}
});
obj.name=300;//当这个设置name属性后就会触发set属性
//obj.age=100;//这个虽然设置了但是都没执行,是因为,传的参是name
//get:里面有return,没有return返回undefined set:里面有参数
已经了解到vue是通过数据劫持的方式来做数据绑定的,其中最核心的方法便是通过Object.defineProperty()来实现对属性的劫持,那么在设置或者获取的时候我们就可以在get或者set方法里假如其他的触发函数,达到监听数据变动的目的,无疑这个方法是本文中最重要、最基础的内容之一。
2. 实现最简单的数据绑定
<div id="app">
{{msg}}
<div>
{{arr}}
</div>
<input type="text" v-model="msg" yy="1">
<!-- <div v-for="a in arr"></div> -->
</div>
<script src="vue.js"></script>
<script>
let vm = new Vue({
el:"#app",
data:{
// ueObserver 数据监听器,把一个普通的 JavaScript 对象传给Vue的data属性,VUE将遍历data中所有的属性,并使用Object.defineProperty()方法把这些属性全部转成set、get方法
msg:"hello",
arr:[1,2,3,4]
}
});
vm.msg=9;
// 当进行complie解析指令时,给每一个元素进行指令解析,并绑定一个更新函数;当数据发生变化之后,是observe通过Object.defineProperty进行监听到,通知对应的更新函数执行,视图就会更新;
可以这么总结一下双向数据绑定的原理
VUE的双向数据绑定原理:
当执行 new Vue() 时,Vue 就进入了初始化阶段,一方面Vue 会遍历 data 选项中的属性,并用 Object.defineProperty 将它们转为 getter/setter,实现数据变化监听功能;另一方面,Vue 的指令编译器Compile 对元素节点的指令进行解析,初始化视图,并订阅Watcher 来更新视图, 此时Wather 会将自己添加到消息订阅器中(Dep),初始化完毕。当数据发生变化时,Observer 中的 setter 方法被触发,setter 会立即调用Dep.notify(),Dep 开始遍历所有的订阅者,并调用订阅者的 update 方法,订阅者收到通知后对视图进行相应的更新。