Vue源码 流程讲解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue源码 流程讲解相关的知识,希望对你有一定的参考价值。
模块分析Vue源码,源码版本2.6.9
场景1:初始化vue实例,渲染到页面,点击handleChangeWeight方法
{
data(){
return {
weight:120
}
},
watch:{
weight(){
console.log(\'change!!!\')
}
},
computed:{
type(){
return this.weight > 150 ? \'胖\' : \'瘦\'
}
},
methods:{
handleChangeWeight(){
this.weight = 200
}
}
}
1, data初始化,weight设置为响应式时,有一个dep保存依赖,在其他变量获取当前weigth时,收集其他变量的Watcher
// 每一个变量都会运行defineReactive
// 一下代码位置src\\core\\observer\\index.js
// 代码有删减
function defineReactive(obj,key,val){
const dep = new Dep() // 依赖
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter () {
const value = val
if (Dep.target) {
dep.depend() // 收集依赖
}
return value
},
set: function reactiveSetter (newVal) {
const value = getter ? getter.call(obj) : val
val = newVal
dep.notify() // 设置值的时候通知其他
}
})
}
2,computed初始化,创建watcher,watcher的lazy是true在最后再执行
var watchers = vm._computedWatchers = Object.create(null);
watchers[\'type\'] = new Watcher(
vm,
getter || noop,
noop,
computedWatcherOptions:{lazy:true}
)
Object.defineProperty(vm, \'type\', {
set:noop,
get:() => {
return computedGetter () {
var watcher = vm._computedWatchers && vm._computedWatchers[key];
if (watcher) {
if (watcher.dirty) {
watcher.evaluate();
}
if (Dep.target) {
// 把computed:type的watcher添加为_update(_render)的依赖
// 在render&&update的getter中调用这个方法,Dep.target=render&&update的watcher
watcher.depend()
}
return watcher.value
}
}
}
})
3,初始化watch
watcher = new Wacther(vm,\'weight\',watch:{weight(){}})
lazy:false 执行geter,获取weight的数值,get方法,收集weight->watcher
watcher = {
cb(){} === weight->watcher,
expression:\'weight\',
get:_=> 处理深度监听\'例如panda.name\',触发weight的get,返回weight的value,
user:true,
value:120
}
4, 在解析完html,转vnode时,调用computed:type的getter方法,调用weight的get方法,收集依赖
_s(type)
5,把computed:type的watcher添加为_update(_render)的依赖
6, 点击change
触发weight的setter,触发依赖watcher.update,
watchers开启一个队列,保存非lazy的watcher,并Promise.resolve().then(flushCallbacks)
函数处理完成
7,调用微服务
调用微任务,flushCallbacks
排序watchers,依次调用watcher.run
watch,update(render),addComputed to update(render)的依赖中
备用小知识
- initWatch内部使用了vm.$watch(expOrFn, handler, options)方法
- 初始化流程initData,initComputed,initWatch,parseHtml,new Wacther : get=> (_update(_render)),
- _render产生vnode
- _update调用patch
- watcher get调用
Watcher.prototype.get = function get () {
pushTarget(this); // push
var value;
var vm = this.vm;
try {
value = this.getter.call(vm, vm);
} catch (e) {
if (this.user) {
handleError(e, vm, ("getter for watcher \\"" + (this.expression) + "\\""));
} else {
throw e
}
} finally {
if (this.deep) {
traverse(value);
}
popTarget(); // pop
this.cleanupDeps(); // 清空
}
return value
};
- _update(_render)是render&&update的getter,在getter调用中,Dep.target=watcher
以上是关于Vue源码 流程讲解的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段
Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段