写作不易,未经作者允许禁止以任何形式转载!
如果觉得文章不错,欢迎关注、点赞和分享!
原文链接:Vue的前世今生
Vue的前世今生
- 2013 尤雨溪个人项目
- 2014.2 0.1版本发布
- 2015.10 1.0版本发布
- 模板语法改进
- 2016.9 2.0版本发布
- 跨端
- 新的渲染机制
- 2019.10 3.0 alpha发布
- 性能
- 架构
- 按需引入
- Composition API
- Proxy observer
- AOT优化
Vue 1 响应式原理
构建响应式对象流程
- walk函数遍历data对象中的属性,调用defineReactive将其变成响应式对象
- 对于对象属性进行递归调用walk,以保证data整个对象树中的属性都是响应式对象。
- defineReactive中使用watchers数组储存watcher,使用Object.defineProperty的get函数收集watcher和返回值,set函数用来设置值和对watchers中的watcher进行视图更新。
Walk函数实现
function walk(data){
Object.keys(data).foreach(key => {
defineReactive(data, key, data[key])
//对象递归调用walk
walk(data[key])
})
}
defineReactive函数实现
function defineReactive(obj, key, value){
let oldValue = value;
const watchers = []
Object.defineProperty(obj, key, {
get(){
//收集watcher
watchers.push(currentWatcher)
return oldValue
},
set(){
if(newValue === oldValue) return;
oldValue = newValue;
watchers.forEach(watcher => wathcer.update())//更新视图
}
})
}
看了这么久Watcher到底是什么?
- Watcher用于获取数据和更新视图,并实现vue指令
- watcher从data中get数据render视图,同时data中的响应式对象劫持当前watcher并“储存”起来
- data更新数据会触发响应式对象的set函数,把get数据时“储存”的watchers取出遍历,“通知”其更新视图。
- watcher“接到data中的数据更新通知”,重新render视图。
- 视图发生变化会触发data的中响应式对象的set函数,循环形成数据流。
- 例:
// vm指向当前组件,el指向当前dom节点,第三个参数为标签类型,第四个为回调函数
// currentWatcher为全局变量指针
// 普通渲染的watcher
Watcher(vm, el, 'text', () =>{
// 将currentWatcher对象指向当前watcher(vdom节点)供响应式对象的get函数获取
currentWatcher = this;
// 读取显示的内容
el.textContext = eval('vm.data.text')
// 解绑currentWatcher,防止发生错误。
currentWatcher = null
})
//带v-if指令的watcher
Watcher(vm, el, 'text', () =>{
// 将currentWatcher对象指向当前watcher(vdom节点)供响应式对象的get函数获取
currentWatcher = this;
// 实现v-if指令,通过判断变量值决定是否显示该元素,v-show原理类似
el.sty