是什么:
采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
为什么:
单向绑定:把Model绑定到View,当我们用JavaScript代码更新Model时,View就会自动更新。因此,我们不需要进行额外的DOM操作,只需要进行Model的操作就可以实现视图的联动更新。
双向绑定:把Model绑定到View的同时也将View绑定到Model上,这样就既可以通过更新Model来实现View的自动更新,也可以通过更新View来实现Model数据的更新。所以,当我们用JavaScript代码更新Model时,View就会自动更新,反之,如果用户更新了View,Model的数据也自动被更新了。
怎么做:
1 借鉴MVVM模式(模型视图视图模型)
2 数据劫持核心API-Object.defineProperty(vue3.0启用Proxy)
3 订阅—发布者模式
4 虚拟DOM(Virtual DOM)和diff(diff算法是vdom中最核心,最关键的部分)
- 通过建立虚拟dom树
document.createDocumentFragment(),方法创建虚拟dom树。 - 一旦被监测的数据改变,会通过Object.defineProperty定义的数据拦截,截取到数据的变化。
- 截取到的数据变化,从而通过订阅——发布者模式,触发Watcher(观察者),从而改变虚拟dom的中的具体数据。
- 最后,通过更新虚拟dom的元素值,从而改变最后渲染dom树的值,完成双向绑定
注意点:
Object.defineProperty缺点:
- 深度监听,需要递归到底,一次性计算量大
- 无法监听新增属性/删除属性(Vue.set Vue.delete)
- 无法原生监听数组,需要特殊处理