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
将来的自己,会感谢现在不放弃的自己!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· 单线程的Redis速度为什么快?
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码