Vue3更新流程

简言

vue3更新流程分析,下面的无论是代码分析还是流程图都不会太往深走,会乱;其中涉及到的其他重要东西,比如响应式,编译器…后面重新写文章去分析

分析的示例代码

<div id="#app">
	<h1>vue3 源码更新流程</h1>
	<div>{{ counter }}</div>
</div>
<script>
	Vue.createApp({
		data() {
			return {
				counter: 0
			}
		},
		mounted() {
			setInterval(() => {
				this.counter++
			}, 1000)
		}
 	})
</script>

流程图

在这里插入图片描述

源码分析

这里咱们按照两个方面去分析

下面所有的代码都是经过简化处理过的,和更新流程不相干的我都会剔除掉,避免理解混乱

1. 更新机制的建立

所在的函数:setupRenderEffect

queueJob:就是将组件的更新函数(也就是effect.update --> run --> componentUpdateFn)放入到更新队列中

const setUpRenderEffect = () => {
	// 组件真正的更新函数
	// 告诉组件如果数据发生变化,我该怎么做才能更新组件
	// 在首次执行渲染的时候,其实已经建立了依赖关系(在之前文章中vue初始化有提到)
	const componentUpdateFn = () => {}


	const effect = (instance.effect = new ReactiveEffect(
		componentUpdateFn,
		() => queueJob(update),
		instance.scope // 不需要关心,和更新流程无关
	))

	// 实际上update函数就是effect.run
	const update = (instance.update = () => effect.run())
}

function queueJob {
	// 这边的代码逻辑要清除,其实只要懂一点,它在温壶queue这个更新队列
	if (job.id == null) {
		queue.push(job)
	} else {
		queue.splice(findInsertionIndex(job.id), 0, job))
	}
	// 重要代码: 启动批量任务执行
	queueFlush()
}

function queueFlush() {
	// 只有处在空闲中的时候才会开始更新
	if (!isFlushing || !isFlushPending) {
		// 代表正在工作中
		isFlushPending = true
		// 重要代码
		// 已异步方式(微任务)去执行flushJobs,在未来的某一时刻会开始刷新queue这个队列
		currentFlushPromise = resolvePromise.then(flushJobs)
	}
}

function flushJobs() {
	循环执行queue里面的每一项
	// queue里的每一项就是effect.update
	effect.update ⇒ effect.run ⇒ fn ⇒ componentUpdateFn ⇒ patch (diff算法开始执行)
}

2. 数据改变到放入更新队列

const PublicInstanceProxyHandlers = () => {
	get() {} // 很重要,但是在更新流程中不用关心
	set() {
		// 注意此时data是一个new Proxy构建的数据
		data[key] = value
	}
}

// baseHandlers.js
function createSetter() {
	// 最最重要的就是
	trigger()
}

function trigger() {
	// 在数据访问的时候,用户执行track -> trackEffect,会维护一个对象的key和组件更新函数之间关系的map, 
	// 结构大约是这样的
	const deps = Map(
		counter: Set([ReactiveEffect])
	)
	// 这个函数的作用就是取出来更新函数,然后执行triggerEffect()
	triggetEffect()
}

function triggetEffect() {
	if (effect.scheduler) {
      // 异步更新
      // 最终都是走componentUpdateFn
      // effect.scheduler 会调用的是 queueJob(update),
      // 整个流程就清晰起来了
      effect.scheduler()
    } else {
      // 立刻更新
      effect.run()
    }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值