vue 是常见的 mvvm 框架,实现数据,视图双向绑定的原理主要是数据劫持结合发布-订阅模式,通过 Object.defineProperty 来劫持 data 各个的属性,属性初始化取值时添加订阅,属性取值变化时触发 setter 通知订阅触发回调更新视图
下面根据 vue 的源码,实现简易版本的 mvvm,使用方式和 vue 一样,主要实现 v-model 命令和文本插值,使用方式如下:
html
<body> |
整体思路
整体思路如上图所示:
新建 mvvm 实例 是整个程序的入口,在新建过程中
首先用 Observer 劫持 data 所有属性:
- 创建 Dep 实例 dep,Dep是用来收集订阅和通知订阅更新
- 创建 getter,若 Dep.target 存在,dep 添加订阅 watcher
- 创建 setter,如果触发 setter,通过 dep 通知 watcher 更新
然后创建 Compiler 结合 data 进行模板编译:
解析到编译的数据,每个数据创建watcher,在创建过程中:
Dep.target 指向创建的watcher,
取值时触发 getter,给 dep 添加订阅
Dep.target = null 解除引用
根据 data 编译模板渲染到页面,初始化视图
完成之后,数据变化 —— 触发 setter,setter 里调用 dep.notify() —— dep 通知所有订阅的 watcher 更新 —— 更新视图