当前位置: 首页 > Web前端 > vue.js

Vue3生命周期完整指南

时间:2023-04-01 10:44:08 vue.js

作者:MichaelThiessen译者:前端小智拥有向上积极心态的人。本文已收录到GitHubhttps://github.com/qq44924588...,文章已分类,也整理了很多我的文档和教程资料。最近开源了一个Vue组件,但是还不够完善。欢迎大家一起完善,也希望大家能给个star支持一下。谢谢。github地址:https://github.com/qq44924588...Vue2和Vue3中的生命周期钩子的工作原理非常相似,我们仍然可以访问相同的钩子并希望将它们用于相同的场景。如果你的项目使用了optionsAPI,你不需要更改任何代码,因为Vue3与以前的版本兼容。当然,我们使用Vue3是为了使用它的组合API。在组合API中访问这些钩子的方式略有不同。组合API在大型Vue项目中特别有用。本文主要内容:什么是Vue生命周期钩子在optionsAPI中使用Vue生命周期钩子在组合API中使用Vue3生命周期钩子更新Vue2到Vue3的生命周期钩子代码分别查看Vue2和Vue3生命周期钩子CreateMountUpdateUnmountActivateVue3中的新调试钩子什么是Vue生命周期钩子首先,让我们看一下OptionsAPI和CompositionAPI中的Vue3生命周期钩子图。在深入细节之前,这加深了我们的理解。本质上,每个主要的Vue生命周期事件都被分成两个钩子,在事件之前和之后调用。Vue应用程序中有4个主要事件(8个主要挂钩)。create——在创建组件时执行mount——在挂载DOM时执行更新——在修改响应数据时执行destroy——在元素被销毁之前运行在选项API中使用Vue生命周期钩子使用选项API,生命周期钩子是暴露的Vue实例上的选项.我们不需要导入任何东西,只需调用这个方法并为这个生命周期钩子编写代码。例如,假设我们想要访问mounted()和updated()生命周期钩子,我们可以这样写://optionsAPI在组合API中使用Vue3生命周期钩子在组合API中,我们需要将生命周期钩子导入到项目中才能使用它们,这有助于保持轻盈的项目。//CombinedAPIimport{onMounted}from'vue'除了beforecate和created(被setup方法本身替代)之外,我们可以在setup方法中访问API生命周期钩子的9个选项:onBeforeMount-在调用之前调用mountstartsCall:关联的render函数被第一次调用。onMounted——当组件被挂载时调用onBeforeUpdate——当数据更新时调用,在虚拟DOM被修补之前。这适用于在更新之前访问现有的DOM,例如手动移除添加的事件监听器。onUpdated–在虚拟DOM由于数据更改而重新渲染和修补后调用此挂钩。onBeforeUnmount–在卸载组件实例之前调用。在此阶段,该实例仍然可以正常运行。onUnmounted–在卸载组件实例后调用。当这个钩子被调用时,组件实例的所有指令都被解除绑定,所有事件监听器被移除,所有子组件实例被卸载。onActivated–当激活缓存组件时调用。onDeactivated–当keep-alive缓存的组件被停用时调用。onErrorCaptured–当捕获到来自后代的错误时调用。该挂钩接收三个参数:错误对象、发生错误的组件实例以及包含错误来源信息的字符串。该钩子可以返回false以防止错误进一步向上传播。用例://CompositionAPIUpdateVue2'slifecyclehookcodetoVue3这个从Vue2到Vue3的生命周期映射直接从Vue3CompositionAPI文档中获取:beforeCreate->createdwithsetup()->createdwithsetup()beforeMount->onBeforeMountmounted->onMountedbeforeUpdate->onBeforeUpdateupdated->onUpdatedbeforeDestroy->onBeforeUnmountdestroyed->onUnmountedererrorCaptured->onErrorCaptured深入了解每个生命周期钩子我们现在了解了两件重要的事情:我们可以使用的不同生命周期钩子在CompositionAPI中使用它们让我们深入了解每个生命周期钩子看看它们是如何使用的。我们可以在每个钩子中编写具体的代码来测试OptionsAPI和CompositionAPI之间的区别。beforeCreate()-选项API因为创建的钩子是用来初始化所有响应数据和事件的东西,beforeCreate不能访问组件的任何响应数据和事件。以下面的代码块为例://optionsAPIexportdefault{data(){return{val:'hello'}},beforeCreate(){console.log('Valueofvalis:'+this.val)}}val的输出值是undefined,因为数据还没有初始化,我们不能在这里调用组件方法。如果您想查看可用内容的完整列表,建议只运行console.log(this)以查看已初始化的内容。在使用选项API时,这在其他挂钩中也很有用。created()–optionAPI如果我们想在创建组件时访问组件的数据和事件,我们可以将上面的beforeCreate替换为created。//OptionsAPIexportdefault{data(){return{val:'hello'}},created(){console.log('Valueofvalis:'+this.val)}}输出Valueofvalis:hello,因为我们已经初始化了数据。在处理读取/写入反应数据时,使用创建的方法很有用。例如,要进行API调用然后存储值,您可以在此处执行。最好在此处执行此操作而不是在mounted中执行此操作,因为它发生在Vue的同步初始化期间,我们需要执行所有数据读/写。组合API的创建挂钩如何?对于使用组合API的Vue3生命周期钩子,使用setup()方法而不是before和created。这意味着,放在这些方法中的任何代码现在都只在设置方法中。//CombinedAPIimport{ref}from'vue'exportdefault{setup(){constval=ref('hello')console.log('Valueofvalis:'+val.value)return{val}}}beforeMount()和onBeforeMount()在组件DOM实际渲染和挂载之前被调用。在这一步,根元素还不存在。在选项API中,可以使用this.$els访问它。在组合API中,为了做到这一点,必须在根元素上使用ref。//OptionAPIexportdefault{beforeMount(){console.log(this.$el)}}组合API使用ref://CompositionAPIimport{ref,onBeforeMount}from'vue'exportdefault{setup(){constroot=ref(null)onBeforeMount(()=>{console.log(root.value)})return{root}},beforeMount(){console.log(this.$el)}}由于app.$el尚未创建,因此输出将是未定义的。mounted()和onMounted()在组件第一次渲染后调用,元素现在可用,也允许直接访问DOM,在选项API中我们可以使用this.$el访问我们的DOM,在组合API中,我们需要使用refs来访问Vue生命周期钩子中的DOM。import{ref,onMounted}from'vue'exportdefault{setup(){/*CompositionAPI*/constroot=ref(null)onMounted(()=>{console.log(root.value)})return{root}},mounted(){/*OptionAPI*/console.log(this.$el)}}beforeUpdate()和onBeforeUpdate()在更新数据时调用,在修补虚拟DOM之前。这适用于在更新之前访问现有的DOM,例如手动移除添加的事件监听器。beforeUpdate对于跟踪对组件的编辑次数,甚至跟踪创建“撤消”功能的操作很有用。updated()和onUpdated()在DOM更新后,会调用updated方法。<模板>

{{val}}|编辑了{{count}}次

ClicktoChange
OptionAPI方法:exportdefault{data(){return{val:0}},beforeUpdate(){console.log("beforeUpdate()val:"+this.val)},updated(){console.log("updated()val:"+this.val}}API组合方式:import{ref,onBeforeUpdate,onUpdated}from'vue'exportdefault{setup(){constcount=ref(0)constval=ref(0)onBeforeUpdate(()=>{count.value++;console.log("beforeUpdate");})onUpdated(()=>{console.log("updated()val:"+val.value)})return{count,val}}}这些方法很有用,但是更多的场景,我们需要使用watch方法检测这些数据watch之所以有用,是因为它给出了after-change数据的旧值和新值。另一种选择是使用计算属性来根据元素更改状态。beforeUnmount()和onBeforeUnmounted()在卸载组件实例之前被调用。在这个阶段,实例仍然是compl非常健康。在选项API中,移除事件侦听器的示例如下所示。//optionsAPIexportdefault{mounted(){console.log('mount')window.addEventListener('resize',this.someMethod);},beforeUnmount(){console.log('unmount')window.removeEventListener('resize',this.someMethod);},methods:{someMethod(){//dosmth}}}//组合APIimport{onMounted,onBeforeUnmount}from'vue'exportdefault{setup(){constsomeMethod=()=>{//dosmth}onMounted(()=>{console.log('mount')window.addEventListener('resize',someMethod);})onBeforeUnmount(()=>{console.log('unmount')window.removeEventListener('resize',someMethod);})}}实际执行此操作的一种方法是在Vite、vue-cli或任何支持热重载的开发环境中,当您更新代码时,某些组件将自行卸载并安装。卸载组件实例后调用unmounted()和onUnmounted()。当这个钩子被调用时,组件实例的所有指令都被解除绑定,所有事件监听器被移除,所有子组件实例被卸载。import{onUnmounted}from'vue'exportdefault{setup(){/*CompositionAPI*/onUnmounted(()=>{console.log('unmounted')})},unmounted(){/*OptionsAPI*/console.log('unmounted')}}activated()和onActivated()在激活缓存组件时调用。比如我们使用keep-alive组件来管理不同的tab视图,每次切换tab时,当前tab都会运行activated钩子。假设我们对以下动态组件使用keep-alive包装器。在Tab1.vue组件内部,我们可以像这样访问激活的钩子。deactivated()和onDeactivated()被调用的keep-alive缓存组件停用什么时候。此挂钩在保存用户数据和在特定视图失去焦点时触发动画等用例中很有用。import{onActivated,onDeactivated}from'vue'exportdefault{setup(){onActivated(()=>{console.log('Tab1Activated')})onDeactivated(()=>{console.log('Tab1Deactivated')})}}现在,当我们在选项卡之间切换时,每个动态组件的状态将被缓存并保存。Vue3调试钩子Vue3为我们提供了两个可用于调试目的的钩子。onRenderTrackedonRenderTriggered这两个事件都带有一个调试器事件,该事件告诉您哪个动作跟踪了组件以及该动作的目标对象和键。onRenderTracked在被跟踪的虚拟DOM被重新渲染时被调用。挂钩接收调试器事件作为参数。该事件告诉您哪个动作跟踪了组件以及动作的目标对象和键。加入购物车

购物车({{car??t}})

constapp=Vue.createApp({data(){return{car??t:0}},renderTracked({key,target,type}){console.log({key,target,type})/*当组件第一次渲染时,这将被记录:{key:"cart",target:{car??t:0},type:"get"}*/},methods:{addToCart(){this.cart+=1}}})app.mount('#app')renderTracked在重新渲染虚拟DOM时触发。与renderTracked类似,它接收调试器事件作为参数。此事件告诉您什么操作触发了重新渲染,以及该操作的目标对象和键。用法:加入购物车

Cart({{car??t}})

constapp=Vue.createApp({data(){return{car??t:0}},renderTriggered({key,target,type}){console.log({key,target,type})},方法:{addToCart(){this.cart+=1/*这将导致调用renderTriggered{key:"cart",target:{car??t:1},type:"set"}*/}}})app.mount('#app')总结无论您选择使用选项API还是组合API,重要的是不仅要知道要使用哪个生命周期挂钩,还要知道为什么要使用它。对于许多问题,可以使用多个生命周期钩子。但很高兴知道哪个最适合您的用例。无论如何,您应该考虑一下并有充分的理由选择特定的生命周期挂钩。我希望这可以帮助您更多地了解生命周期钩子以及如何在您的项目中实现它们。~终于,我是个洗碗工,我去洗碗了,骨头都白了。代码部署后可能存在的bug,无法实时获知。事后为了解决这些bug,花费了大量的时间在日志调试上。顺便推荐一个好用的bug监控工具Fundebug。原文:https://learnvue.co/2020/12/h...每周更新交流文章。可以微信搜索“大千世界”立即阅读更新(比博客早一两篇),本文已收录到GitHubhttps://github.com/qq449245884/xiaozhi,我整理了一篇我的很多文件。欢迎加星和改进。可以参考考点面试。也关注公众号,后台回复福利就能看到福利,你懂的。