通过手写一个MVVM框架,从而理解Vue.js的响应式原理
涉及到的知识点包括:
Object.defineProperty 实现数据拦截
观察者模式
Object.defineProperty 实现数据拦截
语法:Object.defineProperty(obj, key, descriptor)
基本用法
|
|
configurable 可否删除
|
|
configurable 的值设置为 false 后(如果没设置,默认就是 false),就无法删除该属性。
enumerable 可否遍历
|
|
设置 enumerable 属性为 false 后,遍历对象的时候会忽略当前属性(如果未设置,默认就是 false不可遍历)。
writable 可否修改
|
|
get和set
注意,get
和value
不能同时存在!
- get:一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。该方法返回值被用作属性值。默认为 undefined。
- set:一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数newVal,并将该参数的新值分配给该属性。默认为 undefined。
数据劫持
写一个数据劫持函数observe(),效果如下:
说干就干!
以上,observe方法实现了数据的劫持
观察者模式(发布/订阅模式)
一个典型的观察者模式应用场景是用户在一个网站订阅主题
- 多个用户(观察者,Observer)都可以订阅某个主题(Subject)
- 当主题内容更新时订阅该主题的用户都能收到通知
以下是代码实现
Subject是构造函数,new Subject() 创建一个主题对象,该对象内部维护订阅当前主题的观察者数组。主题对象上有一些方法,如添加观察者(addObserver)、删除观察者(removeObserver)、通知观察者更新(notify)。 当notify 时实际上调用全部观察者 observer 自身的 update 方法。
Observer 是构造函数,new Observer() 创建一个观察者对象,该对象有一个 update 方法。
|
|
上面的代码中,主题被观察者订阅的写法是 subject.addObserver(observer), 不是很直观,改写成 observer.subscribeTo(subject)
|
|
MVVM单向绑定的实现
MVVM (Model-View-ViewModel) 是一种用于把数据和视图层分离的设计模式。
MVVM 中的 Model 表示应用程序使用的数据,比如一个用户账户信息(名字、头像、电子邮件等)。Model 保存信息,但通常不处理行为,不会对信息进行再次加工。数据的格式化是由View 处理的。行为一般认为是业务逻辑,封装再 ViewModel 中。
View 是与用户进行交互的桥梁。
ViewModel 充当数据转换器
- 将 Model 信息转换为 View 的信息
- 将命令从 View 传递到 Model。
假设有如下代码,data 里的name会和视图中的绑定,修改 data 里的值,会直接引起视图中对应数据的变化。
|
|
|
|
实现一个Vue