vue3的钩子函数分析

278 阅读1分钟

1、执行下面代码

<script src="../../dist/vue.global.js"></script>
<div id="demo">
  <h1>
    {{count}}
  </h1>
</div>
<script>
  const { createApp, ref,toRefs, reactive, onUpdated, onMounted,onBeforeMount,onBeforeUpdate} = Vue
  var app = createApp({
    setup(){
      var count = ref(1)
      onBeforeMount(()=>{
        debugger
      })
      onMounted(()=>{
        debugger
        count.value++
      })
      onBeforeUpdate(()=>{
        debugger
      })
      onUpdated(()=>{
        debugger
      })
      return {
        count,
      }
    },
    beforeCreate(){
      debugger
    },
    created(){
      debugger
    },
    beforeMount(){
      debugger
    },
    mounted(){
      debugger
    },
    beforeUpdate(){
      debugger
    },
    updated(){
      debugger
    },
    beforeUnmount(){
      debugger
    },
    unmounted(){
      debugger
    }
  })
  app.mount('#demo')
  setTimeout(()=>{
   app.unmount()
  },1000)
</script>

2、调用栈分析

依次跳出断点可以发现出钩子函数的执行顺序 如下

beforeCreate

-> created

->onMounted ->mounted

->onBeforeUpdate ->beforeUpdate

->onUpdated ->updated

->onbeforeUnmount ->beforeUnmount

->onUnmounted ->onMounted

先来看看beforeCreate是在什么时候执行的,且beforeCreate 和 created之间都做了那些事情? 如下图所知,beforeCreate的执行关联到了setupComponent,直到执行了applyOptions,在beforeCreate 和 created之间对用户转入的options做了处理,比如对data做reactive处理,对methods遍历到ctx上,且绑定this

image.png

beforeCreate

![image.png](p3-juejin.byteimg.com/tos-cn-i-k3…?

created

image.png

mounted 和 onMounted,flushPostFlushCbs内部遍历pendingPostFlushCbs分别执行,这里的if(m) 其中m是一个数组,是多个onMounted钩子

image.png flushPostFlushCbs执行如下图所示 image.png 接下来我们来看看 onMounted是如何收集回调钩子的,如下图打上断点,然后找到下一个满足条件断点调用栈,就知道vue2写法的mounted钩子是如何处理的,他是在applyoptions时候进行了registerLifecycleHook(onMounted, mounted), mounted是用户写的函数

image.png

beforeUpdate,如下图可知

image.png

updated

跟mounted类似的流程

if (m) {
  queuePostRenderEffect(m, parentSuspense)
}
if (u) {
  queuePostRenderEffect(u, parentSuspense)
}

image.png

onBeforeUnmount 当执行了app.unmount()时候

image.png

onUnmounted

image.png

跟mounted 和 updated类似的流程

if (m) {
  queuePostRenderEffect(m, parentSuspense)
}
if (u) {
  queuePostRenderEffect(u, parentSuspense)
}
if (um) {
  queuePostRenderEffect(um, parentSuspense)
}

image.png

3.实例上的m 等钩子函数相关的属性数如何声明的

我们声明的钩子函数 全都给声明到了实例的m等相关的属性上,且他们的值都是数组,因为可以使用多个

image.png