vue3认识组件与生命周期(小满zs vue3 笔记十二)

tip0: 调用用下面这两个钩子,收集依赖与触发依赖更新

1
2
3
4
5
6
7
8
// 依赖收集,用来调试用
onRenderTracked(e => {
  console.log('------onRenderTracked--', e)
})
// 触发依赖,用来调试用
onRenderTriggered(e => {
  console.log('------onRenderTriggered--', e)
})

  

tip: 1. 组件的认识

*组件基础

  每一个.vue 文件呢都可以充当组件来使用,每一个组件都可以复用,

1
如下lifeCycle(或helloWorld)充当子组件

1
在引用时,只需要通过import引入,vue3 不需要注册组件,可以直接使用就可以如下: <br><template> <br><!-- 直接在这里使用,不需要通过components再启用--> <br>    <life-cycle></life-cycle><br></template> <br><script setup lang="ts"> <br>  import lifeCycle from './components/lifeCycle.vue'; <br></script>

组件生命周期

1
beforeCreate 和 created 这两个生命周期的,setup(代替vue2 beforeCreate->created)->beforeMount->mounted->beforeUpdate->updated->beforeUnmount->unmounted

onBeforeMount()

在组件DOM实际渲染安装之前调用。在这一步中,根元素还不存在。

onMounted()

在组件的第一次渲染后调用,该元素现在可用,允许直接DOM访问

onBeforeUpdate()

数据更新时调用,发生在虚拟 DOM 打补丁之前。

onUpdated()

DOM更新后,updated的方法即会调用。

onBeforeUnmount()

在卸载组件实例之前调用。在这个阶段,实例仍然是完全正常的。

onUnmounted()

卸载组件实例后调用。调用此钩子时,组件实例的所有指令都被解除绑定,所有事件侦听器都被移除,所有子组件实例被卸载。

 

 源码: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
在控制台看到的都是这些枚举值
export const enum LifecycleHooks {
BEFORE_CREATE = 'bc',
CREATED = 'c',
BEFORE_MOUNT = 'bm',
MOUNTED = 'm',
BEFORE_UPDATE = 'bu',
UPDATED = 'u',
BEFORE_UNMOUNT = 'bum',
UNMOUNTED = 'um',
DEACTIVATED = 'da',
ACTIVATED = 'a',
RENDER_TRIGGERED = 'rtg',
RENDER_TRACKED = 'rtc',
ERROR_CAPTURED = 'ec',
SERVER_PREFETCH = 'sp'
}

源码解析: 

apiLifecycle.ts/render.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
核心部分
// 创建hook做个缓存
export function injectHook(
  type: LifecycleHooks,
  hook: Function & { __weh?: Function },
  target: ComponentInternalInstance | null = currentInstance,
  prepend: boolean = false
): Function | undefined {
  if (target) {
    // 如果有hook函数直接返回否则创建一个空数组
    const hooks = target[type] || (target[type] = [])
    // cache the error handling wrapper for injected hooks so the same hook
    // can be properly deduped by the scheduler. "__weh" stands for "with error
    // handling".
    const wrappedHook =
      hook.__weh ||
      (hook.__weh = (...args: unknown[]) => {
        if (target.isUnmounted) {
          return
        }
        // disable tracking inside all lifecycle hooks
        // since they can potentially be called inside effects.
        // 先停止收集避免重复收集依赖
        pauseTracking()
        // Set currentInstance during hook invocation.
        // This assumes the hook does not synchronously trigger other hooks, which
        // can only be false when the user does something really funky.
        // 设置target为当前实例
        setCurrentInstance(target)
        const res = callWithAsyncErrorHandling(hook, target, type, args) // 执行完成钩子
        unsetCurrentInstance() // 清空当前实例
        resetTracking() // 恢复依赖收集
        return res
      })
    if (prepend) {
      hooks.unshift(wrappedHook)
    } else {
      hooks.push(wrappedHook)
    }
    return wrappedHook
  } else if (__DEV__) {
    const apiName = toHandlerKey(ErrorTypeStrings[type].replace(/ hook$/, ''))
    warn(
      `${apiName} is called when there is no active component instance to be ` +
        `associated with. ` +
        `Lifecycle injection APIs can only be used during execution of setup().` +
        (__FEATURE_SUSPENSE__
          ? ` If you are using async setup(), make sure to register lifecycle ` +
            `hooks before the first await statement.`
          : ``)
    )
  }
}
// render.ts调用
componentUpdateFn 函数里用来更新
没有挂载创建并挂载
创建->render->patch->hook执行副作用函数->mounted
否则已经挂载了就更新
更新钩子-> 更新之前beforeUpdate -> render -> patch-> 执行更新hook副作用函数->updated
unmountComponent 销毁函数
执行函数beforeUnmount-> 卸载所有数据unmountChildren-> unmouted->卸载节点

  

测试代码如下:

1
2
3
4
5
6
7
8
9
<template>
  <life-cycle v-if="lifeFlag"></life-cycle>
  <button @click="lifeFlag = !lifeFlag">创建与销毁</button>
</template>
<script setup lang="ts">
import lifeCycle from './components/lifeCycle.vue';
import { ref } from 'vue'
const lifeFlag = ref<Boolean>(true)
</script>

生命周期组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<template>
  <h3>我是组件</h3>
  <div ref="div">{{  str }}</div>
  <button @click="change">修改</button>
</template>
 
<script setup lang='ts'>
import { onBeforeMount, onBeforeUnmount, onBeforeUpdate, onMounted,
onUnmounted, onUpdated, ref, onRenderTracked, onRenderTriggered } from 'vue';
 
// beforeCreate created setup语法糖是没有这两个函数的生命周期的
console.log('setup')
const str = ref<string>('组件')
const div = ref<HTMLDivElement>()
const change = () => {
  console.log('修改组件了')
  str.value = '修改组件了'
}
// 创建完成之前读不到dom
onBeforeMount(() => {
  console.log('创建完成之前-onBeforeMount', div.value)
})
// 创建完成
onMounted(() => {
  console.log('创建完成-onMounted', div.value)
})
// 更新组件之前
onBeforeUpdate(() => {
  console.log('更新组件之前-onBeforeUpdate', div.value?.innerText)
})
// 更新
onUpdated(() => {
  console.log('更新完成-onUpdated', div.value?.innerText)
})
// 销毁之前
onBeforeUnmount(() => {
  console.log('销毁之前-onBeforeUnmount')
})
// 销毁完成
onUnmounted(() => {
  console.log('销毁完成-onUnmounted')
})
 
// 依赖收集,用来调试用
onRenderTracked(e => {
  console.log('------onRenderTracked--', e)
})
// 触发依赖,用来调试用
onRenderTriggered(e => {
  console.log('------onRenderTriggered--', e)
})
</script>

 

 

 

 

  

 引用文章: https://xiaoman.blog.csdn.net/article/details/122811060

posted @   TheYouth  阅读(127)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· 单线程的Redis速度为什么快?
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
点击右上角即可分享
微信分享提示