Vue3源码解读之patch

本文深入讲解Vue3的patch过程,涉及componentEffect、processFragment、patchBlockChildren等关键函数。通过一个例子展示数据变更如何影响DOM更新,详细解析patch流程,包括处理Fragment、Element和Keyed Children的情况。
摘要由CSDN通过智能技术生成

例子代码

本篇将要讲解dom diff,那么咱们结合下面的例子来进行讲解,这个例子是在上一篇文章的基础上,加了一个数据变更,也就是list的值发生了改变。html中增加了一个按钮change,通过点击change按钮来调用change函数,来改变list的值。例子位于源代码/packages/vue/examples/classic/目录下,下面是例子的代码:

const app = Vue.createApp({
   
    data() {
   
        return {
   
            list: ['a', 'b', 'c', 'd']
        }
    },
    methods: {
   
        change() {
   
            this.list = ['a', 'd', 'e', 'b']
        }
    }
});
app.mount('#demo')

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport"
          content="initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no,target-densitydpi=medium-dpi,viewport-fit=cover"
    />
    <title>Vue3.js hello example</title>

    <script src="../../dist/vue.global.js"></script>
</head>
<body>
<div id="demo">
    <ul>
        <li v-for="item in list" :key="item">
            {
  {item}}
        </li>
    </ul>
    <button @click="change">change</button>
</div>
<script src="./hello.js"></script>
</body>
</html>

Vue3源码视频讲解:进入学习

源码解读

关于Vue3中数据发生变更,最终影响到页面发生变化的过程,我们本篇文章只对componentEffect以及以后的代码进行讲解,对于数据变更后,是如何执行到componentEffect函数,以及为何会执行componentEffect,后面的文章再进行讲解。

componentEffect

来看下componentEffect更新部分的代码:

  // @file packages/runtime-core/src/renderer.ts
  function componentEffect() {
   
    if (!instance.isMounted) {
   
        // first render
    } else {
   
        let {
   next, bu, u, parent, vnode} = instance
        let originNext = next
        let vnodeHook: VNodeHook | null | undefined

        if (next) {
   
            updateComponentPreRender(instance, next, optimized)
        } else {
   
            next = vnode
        }
        next.el = vnode.el

        // beforeUpdate hook
        if (bu) {
   
            invokeArrayFns(bu)
        }
        // onVnodeBeforeUpdate
        if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) {
   
            invokeVNodeHook(vnodeHook, parent, next, vnode)
        }
        const nextTree = renderComponentRoot(instance)
        const prevTree = instance.subTree
        instance.subTree = nextTree

        if (instance.refs !== EMPTY_OBJ) {
   
            instance.refs = {
   }
        }
        patch(
            prevTree,
            nextTree,
            hostParentNode(prevTree.el!)!,
            getNextHostNode(prevTree),
            instance,
            parentSuspense,
            isSVG
        )
        next.el 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值