核心原理

MVVM 双向数据绑定, 数据驱动视图
Vue 实现 MVVM 采用 数据劫持 + 发布订阅模式 :
当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用Object.defineProperty 把这些 property 全部转为 getter/setter。
Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。
这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更。
每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。

Object.defineProperty(obj,prop,descriptor)
obj 要定义属性的对象。
prop 要定义或修改的属性的名称或 Symbol。
descriptor 要定义或修改的属性描述符
descriptor 中一些属性描述符
对象里目前存在的属性描述符有两种主要形式:数据描述符 和 存取描述符。数据描述符 是一个具有值的属性,该值可以是可写的,也可以是不可写的。存取描述符 是由 getter 函数和 setter 函数所描述的属性。一个描述符只能是这两者其中之一;不能同时是两者。
这两种描述符都是对象。它们共享以下可选键值(默认值是指在使用 Object.defineProperty() 定义属性时的默认值):
configurable: 是否可以配置(修改)以及是否可以删除, 默认为 false
enumerable:是否可以遍历,默认为 false
数据描述符还具有以下可选键值:
value
该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined。
writable
当且仅当该属性的 writable 键值为 true 时,属性的值,也就是上面的 value,才能被赋值运算符改变。默认为 false。
存取描述符还具有以下可选键值:
get
属性的 getter 函数,如果没有 getter,则为 undefined。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。默认为 undefined。
set
属性的 setter 函数,如果没有 setter,则为 undefined。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。默认为 undefined。
实现简单的 Vue
实现一个简单的 MVVM 大概分为三个步骤:1. 数据劫持,观察数据变化;2. 模板编译;3. Watcher 根据数据变化 通知 watcher ,使相关的组件重新渲染

1 new MVVM
MVVM 作为连接 Complie 和 Observer 的 桥梁而存在。

2. 数据劫持
遍历 data 内的所有数据, 将他们转 为 set 和 get 的形式。

3. 模板编译
将模板中的所有含 data 中的数据,形式如 {{ a }}, v- model = 'a ',全部替换成 data 中的 数值,并且在这个阶段给每个data 中的数据添加 watcher,当该值 发生变化的时候,通知 watcher 进行 更新。

4. watcher
给模板中的所有含 data 中的数据 添加一个 watcher,当这个数据发生变化的时候,触发 watcher,将模板中的 数据进行更新。

5. 发布订阅
订阅 模板中同一个 data 所对应的所有 watcher, 当这个数据改变时候,通知这个数据对应的所有 watcher, 进行更新。


总结
Vue MVVM 采用 数据劫持 + 发布订阅的方式
首先 将 data 中的数据 全部转换 成 set 和 get 的形式; 再编译模板,将模板中的 {{}} , v-XX 中的变量 替换成 data 中的数据;
在 编译模板的过程中,给 每一个模板中的变量增加一个 watcher,这个 watcher 有 数据变化时所对应的将 模板中的数据 替换为最新的数据的 处理函数,将这个 watcher 添加到 这个变量订阅 的 数组中,一个变量对应一个 wathcer 数组;
当数据发生变化,触发 set 方法,在 set 中 发布 该数据 对应的 watcher 数组,依次执行 watcher,更新 模板中的数据。
收获: 理解 发布订阅模式的 实际应用。
网友评论