我猜测这篇文章的访问量在博客 Analytics 的页面访问量榜单里应该是列位不低的,因为——我标题党了\ud83d\ude33。
双向数据绑定一直被认为是各 MVVM 框架的核心特性,在开发中也是无时不刻都在使用。而我一直是作为一个看客去了解别人博文中的 Vue 双向数据绑定,没有自己去深究并手动实现过(反省)。这篇文章,我将从设计模式、技术原理、原生实现等多个方面去解析 Vue 中的双向数据绑定,当然了,在Vue3 发布之际,也应了解下 Vue3 下的双向数据绑定。
在MVVM 架构下,数据层 Model 和视图层 View 通过 View Model 层进行连接和交互,这个 ViewModel 即为连接视图和数据的桥梁,作数据和逻辑处理工作,指的正是双向数据绑定。
双向数据绑定实现的效果就是在更新 JavaScript 中的数据(定义的变量)时同步修改视图(DOM 节点),修改视图时也同步回数据层:
双向数据绑定演示
以一个开发者的角度应该不难想到,视图到数据方向的改动需要监听 DOM 的变化再同步赋值给 JavaScript 的变量,比如给添加change或input监听事件并在事件处理函数中给变量赋值,实际这也正是v-model指令做的很重要的一件事。
另一个方向,关键词还是「监听」——监听 JavaScript 数据的变化,再去相应更新 DOM,此处的监听及处理就是 Vue 的双向数据绑定实现方式——发布订阅模式+数据劫持。
发布订阅模式也称为观察者模式,是一种行为设计模式,设计意图也很明显了,允许定义一种订阅的机制,在对象发生一定的事件时通知观察着这个对象的其它对象。所以发布订阅模式一定存在以下三个模型对象:
目标对象:被观察的对象。发布者:当目标对象发生变化时,向其他对象发出通知。订阅者:可以执行一些操作来反应发布者的通知。
真实世界中的发布订阅模式例子非常之多,比如你(订阅者)订阅了我的博客(目标对象),就毋需每次打开我的博客站点来查看是否更新了新博文,而我(发布者)会在每次发布新文章时都通过 RSS 在RSS Feed Reader 等订阅工具上通知你。
换置到双向数据绑定中,订阅者就是一个用来操作各 DOM 节点的公共方法,需要观察数据的改动来改动自己(作出反应),数据就是被观察的目标对象,那发布者是谁呢?