一:实现双向绑定的方法
可以实现双向绑定的方法有很多,KnockoutJS基于观察者模式的双向绑定,Ember基于数据模型的双向绑定,Angular基于脏检查的双向绑定,基于数据劫持的双向绑定(常见的基于数据劫持的双向绑定有两种实现:Object.defineProperty和Proxy)
二:基于数据劫持实现的双向绑定的特点
-
什么是数据劫持
vue.js采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫持各个属性的 getter/setter , 在数据变动时发布消息给订阅者,触发响应的监听回调。 -
基于数据劫持双向绑定的实现思路
a. 利用Proxy或Object.defineProperty生成的Observer针对对象/对象的属性进行"劫持",在属性发生变化后通知订阅者
b. 解析器Compile解析模板中的Directive(指令),收集指令所依赖的方法和数据,等待数据变化然后进行渲染
c. Watcher属于Observer和Compile桥梁,它将接收到的Observer产生的数据变化,并根据Compile提供的指令进行视图渲染,使得数据变化促使视图变化
三:v-model指令
1.v-model的原理:v-bind数据绑定 与 v-on处理函数绑定的语法糖
<input v-model="value">
2.想要v-model生效,它必须:
- 接收一个value属性:data => DOM
属性绑定(v-bind):把data的值绑定到元素上,用于显示数据
- 在value值改变的时候,触发input事件:DOM => data
事件绑定(v-on):对元素绑定一个事件,当值变化后把数据传递给控制层,进而来影响数据层
<input v-bind:value="value" v-on:input="value=$event.target.value">
四:数据的响应式
Vue.js 实现响应式的核心是利用了 ES5 的 Object.defineProperty。
响应式的核心
:
vue初始化会用 Object.defineProperty()
给data中的每一个属性添加getter
和setter
,同时创建dep
和watcher
进行依赖收集
和派发更新
,最后通过diff
算法对比新旧vnode差异,通过patch
即时更新DOM
(通过 Object.defineProperty API 劫持数据的变化,在数据被访问的时候收集依赖,然后在数据被修改的时候通知依赖更新。)
Object.defineProperty(obj, prop, descriptor)
//obj 是要在其上定义属性的对象;
//prop 是要定义或修改的属性的名称;
//descriptor 是将被定义或修改的属性描述符。
比较核心的是 descriptor,它有很多可选键值。这里我们最关心的是 get 和 set,get 是一个给属性提供的 getter 方法,当我们访问了该属性的时候会触发 getter 方法;set 是一个给属性提供的 setter 方法,当我们对该属性做修改的时候会触发 setter 方法。
一旦对象拥有了 getter 和 setter,我们可以简单地把这个对象称为响应式对象。
五:Object.defineProperty 与 Proxy
1.Object.defineProperty:
- 只能对属性进行劫持,需要递归遍历对象的每个属性,执行Object.defineProperty把每一层对象数据都变成响应式的(如果定义的响应式数据过于复杂,会有很大的性能负担)
- 不能检测对象属性的添加和删除(需要重新遍历)
2.Proxy
- 在getter中去递归响应式,真正访问到的内部对象才会变成响应式,而不是无脑递归,提升了性能
- 劫持的是整个对象,能检测到对象属性的添加和删除
六:MVVM
1:什么是MVVM
- Model代表模型:用来修改数据和处理业务逻辑;
- View代表视图:是用户在屏幕上看到的结构、布局和外观(UI);
- ViewModel是视图模型:就是一个同步器,用来同步view和model的一个对象。在MVVM框架下,view和model之间是没有直接联系的,他们是通过ViewModel进行交互的。
2:MVVM模式
- MVVM是一种设计思想,实现了数据的双向绑定,当改变了model的数据,view会自动更新;改变view时,model的数据也会自动更新。(它是在单向绑定的基础上,给可输入元素input、textare等添加了input/change事件,通过触发事件来动态修改model)【v-model语法糖】
- ViewModel的实现原理是通过数据劫持(Object.defineProperty)【响应式】
- MVC中Controller(控制器)演变成MVVM中的ViewModel
- MVVM通过数据来显示视图层而不是节点操作
- MVVM主要解决了MVC中大量的dom操作使页面渲染性能降低,加载速度变慢,影响用户体验