作者:Michael Thiessen
译者:前端小智
起源:news
点赞再看,微信搜寻【大迁世界】,B站关注【前端小智】这个没有大厂背景,但有着一股向上踊跃心态人。本文 GitHub https://github.com/qq44924588... 上曾经收录,文章的已分类,也整顿了很多我的文档,和教程材料。

最近开源了一个 Vue 组件,还不够欠缺,欢送大家来一起欠缺它,也心愿大家能给个 star 反对一下,谢谢各位了。

github 地址:https://github.com/qq44924588...

Vue2 和 Vue3 中的生命周期钩子的工作形式十分类似,咱们依然能够拜访雷同的钩子,也心愿将它们能用于雷同的场景。

如果我的项目应用 选项 API,就不用更改任何代码了,因为 Vue3 兼容以前的版本。

当然,咱们用 Vue3 就是要用它的 组合 API组合 API中拜访这些钩子的形式略有不同,组合API在较大的Vue我的项目中特地有用。

本文次要内容:

  1. Vue生命周期钩子有哪些
  2. 选项API中应用 Vue 生命周期钩子
  3. 组合API中应用Vue 3生命周期钩子
  4. 将 Vue2 的生命周期钩子代码更新到 Vue3
  5. 看看Vue 2和Vue 3中的每个生命周期钩子

    1. 创立
    2. 挂载
    3. 更新
    4. 卸载
    5. 激活
  6. Vue 3中的新调试钩子

Vue生命周期钩子有哪些

首先,来看一下 选项API 和 组合 API中 Vue 3生命周期钩子的图表。在深刻细节之前,这能加深咱们的了解。

实质上,每个次要Vue生命周期事件被分成两个钩子,别离在事件之前和之后调用。Vue应用程序中有4个次要事件(8个次要钩子)。

  • 创立 — 在组件创立时执行
  • 挂载 — DOM 被挂载时执行
  • 更新 — 当响应数据被批改时执行
  • 销毁 — 在元素被销毁之前立刻运行

选项API中应用 Vue 生命周期钩子

应用 选项API,生命周期钩子是被裸露 Vue实例上的选项。咱们不须要导入任何货色,只须要调用这个办法并为这个生命周期钩子编写代码。

例如,假如咱们想拜访mounted()updated()生命周期钩子,能够这么写:

// 选项 API<script>        export default {               mounted() {                      console.log('mounted!')               },               updated() {                      console.log('updated!')               }        }</script> 

组合API中应用Vue 3生命周期钩子

在组合API中,咱们须要将生命周期钩子导入到我的项目中,能力应用,这有助于放弃我的项目的轻量性。

// 组合 APIimport { onMounted } from 'vue'

除了beforecatecreated(它们被setup办法自身所取代),咱们能够在setup办法中拜访的API生命周期钩子有9个选项:

  • onBeforeMount – 在挂载开始之前被调用:相干的 render 函数首次被调用。
  • onMounted – 组件挂载时调用
  • onBeforeUpdate – 数据更新时调用,产生在虚构 DOM 打补丁之前。这里适宜在更新之前拜访现有的 DOM,比方手动移除已增加的事件监听器。
  • onUpdated – 因为数据更改导致的虚构 DOM 从新渲染和打补丁,在这之后会调用该钩子。
  • onBeforeUnmount – 在卸载组件实例之前调用。在这个阶段,实例依然是齐全失常的。
  • onUnmounted – 卸载组件实例后调用。调用此钩子时,组件实例的所有指令都被解除绑定,所有事件侦听器都被移除,所有子组件实例被卸载。
  • onActivated – 被 keep-alive 缓存的组件激活时调用。
  • onDeactivated – 被 keep-alive 缓存的组件停用时调用。
  • onErrorCaptured – 当捕捉一个来自子孙组件的谬误时被调用。此钩子会收到三个参数:谬误对象、产生谬误的组件实例以及一个蕴含谬误起源信息的字符串。此钩子能够返回 false 以阻止该谬误持续向上流传。

应用事例:

// 组合 API<script>import { onMounted } from 'vue'export default {   setup () {     onMounted(() => {       console.log('mounted in the composition api!')     })   }}</script>

将 Vue2 的生命周期钩子代码更新到 Vue3

这个从Vue2 到Vue3的生命周期映射是间接从Vue 3 Composition API文档中取得的:

  • beforeCreate -> 应用 setup()
  • created -> 应用 setup()
  • beforeMount -> onBeforeMount
  • mounted -> onMounted
  • beforeUpdate -> onBeforeUpdate
  • updated -> onUpdated
  • beforeDestroy -> onBeforeUnmount
  • destroyed -> onUnmounted
  • errorCaptured -> onErrorCaptured

深刻理解每个生命周期钩子

咱们当初理解了两件重要的事件:

  • 咱们能够应用的不同的生命周期钩子
  • 如何在选项API和组合API中应用它们

咱们深刻一下每个生命周期钩子,看看它们是如何被应用的,咱们能够在每个钩子中编写特定代码,来测试在Options API和Composition API中的各自的区别。

beforeCreate() – 选项 API

因为创立的挂钩是用于初始化所有响应数据和事件的事物,因而beforeCreate无法访问组件的任何响应数据和事件。

以上面的代码块为例:

// 选项 APIexport default {   data() {      return {        val: 'hello'         }   },   beforeCreate() {          console.log('Value of val is: ' + this.val)      }}

val的输入值是 undefined,因为尚未初始化数据,咱们也不能在这调用组件办法。

如果你想查看可用内容的残缺列表,倡议只运行console.log(this)来查看已初始化的内容。当应用选项API时,这做法在其余钩子中也很有用。

created() – 选项 API

如果咱们要在组件创立时拜访组件的数据和事件,能够把下面的 beforeCreatecreated代替。

// 选项APIexport default {   data() {      return {        val: 'hello'         }   },   created() {          console.log('Value of val is: ' + this.val)      }}

其输入为Value of val is: hello,因为咱们曾经初始化了数据。

在解决读/写反馈数据时,应用created 的办法很有用。 例如,要进行API调用而后存储该值,则能够在此处进行此操作。

最好在这里执行此操作,而不是在mounted 中执行此操作,因为它产生在Vue的同步初始化过程中,并且咱们须要执行所有数据读取/写入操作。

那么组合API的创立钩子呢?

对于应用 组合API 的 Vue3 生命周期钩子,应用setup()办法替换beforecatecreated。这意味着,在这些办法中放入的任何代码当初都只在setup办法中。

// 组合APimport { ref } from 'vue'export default {   setup() {         const val = ref('hello')      console.log('Value of val is: ' + val.value)            return {                val     }   }}

beforeMount() and onBeforeMount()

在组件DOM理论渲染装置之前调用。在这一步中,根元素还不存在。在选项API中,能够应用this.$els来拜访。在组合API中,为了做到这一点,必须在根元素上应用ref

// 选项 APIexport default {   beforeMount() {     console.log(this.$el)   } }

组合API中应用 ref:

// 组合 API<template>   <div ref='root'>     Hello World   </div></template> import { ref, onBeforeMount } from 'vue'export default {   setup() {      const root = ref(null)       onBeforeMount(() => {            console.log(root.value)       })       return {          root      }    },    beforeMount() {      console.log(this.$el)    } }

因为app.$el还没有创立,所以输入将是undefined

mounted() and onMounted()

在组件的第一次渲染后调用,该元素当初可用,容许间接DOM拜访

同样,在 选项API中,咱们能够应用this.$el来拜访咱们的DOM,在组合API中,咱们须要应用refs来拜访Vue生命周期钩子中的DOM。

import { ref, onMounted } from 'vue'  export default {   setup() {    /* 组合 API */      const root = ref(null)      onMounted(() => {       console.log(root.value)     })      return {       root     }   },   mounted() { /* 选项 API */     console.log(this.$el)   } } 

beforeUpdate() and onBeforeUpdate()

数据更新时调用,产生在虚构 DOM 打补丁之前。这里适宜在更新之前拜访现有的 DOM,比方手动移除已增加的事件监听器。

beforeUpdate对于跟踪对组件的编辑次数,甚至跟踪创立“吊销”性能的操作很有用。

updated() and onUpdated()

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

<template>    <div>      <p>{{val}} | edited {{ count }} times</p>      <button @click='val = Math.random(0, 100)'>Click to Change</button>    </div> </template> 

选项 API 形式:

 export default {   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'  export default {   setup () {     const count = ref(0)     const val = ref(0)      onBeforeUpdate(() => {       count.value++;       console.log("beforeUpdate");     })      onUpdated(() => {       console.log("updated() val: " + val.value)     })      return {       count, val     }   } }

这些办法很有用,然而对于更多场景,咱们须要应用的watch办法检测这些数据更改。 watch 之所以好用,是因为它给出了更改后的数据的旧值和新值。

另一种抉择是应用计算属性来基于元素更改状态。

beforeUnmount() 和 onBeforeUnmounted()

在卸载组件实例之前调用。在这个阶段,实例依然是齐全失常的。

在 选项 API中,删除事件侦听器的示例如下所示。

// 选项 APIexport default {   mounted() {     console.log('mount')     window.addEventListener('resize', this.someMethod);   },   beforeUnmount() {     console.log('unmount')     window.removeEventListener('resize', this.someMethod);   },   methods: {      someMethod() {         // do smth      }   }} 
// 组合APIimport { onMounted, onBeforeUnmount } from 'vue'  export default {   setup () {      const someMethod = () => {       // do smth     }      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'export default {  setup () { /* 组合 API */    onUnmounted(() => {      console.log('unmounted')    })  },  unmounted() { /* 选项 API */    console.log('unmounted')  }}

activated() and onActivated()

keep-alive 缓存的组件激活时调用。

例如,如果咱们应用keep-alive组件来治理不同的选项卡视图,每次在选项卡之间切换时,以后选项卡将运行这个 activated 钩子。

假如咱们应用keep-alive包装器进行以下动静组件。

<template>   <div>     <span @click='tabName = "Tab1"'>Tab 1 </span>     <span @click='tabName = "Tab2"'>Tab 2</span>     <keep-alive>       <component :is='tabName' class='tab-area'/>     </keep-alive>   </div></template><script>import Tab1 from './Tab1.vue'import Tab2 from './Tab2.vue'import { ref } from 'vue'export default {  components: {    Tab1,    Tab2  },  setup () { /* 组合 API */    const tabName = ref('Tab1')    return {      tabName    }  }}</script>

Tab1.vue组件外部,咱们能够像这样拜访activated钩子。

<template> <div> <h2>Tab 1</h2> <input type='text' placeholder='this content will persist!'/> </div></template><script>import { onActivated } from 'vue'export default { setup() {    onActivated(() => {       console.log('Tab 1 Activated')    }) }} </script>

deactivated() 和 onDeactivated()

keep-alive 缓存的组件停用时调用。

这个钩子在一些用例中很有用,比方当一个特定视图失去焦点时保留用户数据和触发动画。

import { onActivated, onDeactivated } from 'vue'export default {  setup() {    onActivated(() => {       console.log('Tab 1 Activated')    })    onDeactivated(() => {       console.log('Tab 1 Deactivated')    })  }}

当初,当咱们在选项卡之间切换时,每个动静组件的状态都将被缓存和保留。

Vue3 调试钩子

Vue3 为咱们提供了两个可用于调试目标的钩子。

  1. onRenderTracked
  2. onRenderTriggered

这两个事件都带有一个debugger event,此事件通知你哪个操作跟踪了组件以及该操作的指标对象和键。

onRenderTracked

跟踪虚构 DOM 从新渲染时调用。钩子接管 debugger event 作为参数。此事件通知你哪个操作跟踪了组件以及该操作的指标对象和键。

<div id="app">  <button v-on:click="addToCart">Add to cart</button>  <p>Cart({{ cart }})</p></div>
const app = Vue.createApp({  data() {    return {      cart: 0    }  },  renderTracked({ key, target, type }) {    console.log({ key, target, type })    /* 当组件第一次渲染时,这将被记录下来:    {      key: "cart",      target: {        cart: 0      },      type: "get"    }    */  },  methods: {    addToCart() {      this.cart += 1    }  }})app.mount('#app')

renderTracked

当虚构 DOM 从新渲染为 triggered.Similarly 为renderTracked,接管 debugger event 作为参数。此事件通知你是什么操作触发了从新渲染,以及该操作的指标对象和键。

用法:

<div id="app">  <button v-on:click="addToCart">Add to cart</button>  <p>Cart({{ cart }})</p></div>
const app = Vue.createApp({  data() {    return {      cart: 0    }  },  renderTriggered({ key, target, type }) {    console.log({ key, target, type })  },  methods: {    addToCart() {      this.cart += 1      /* 这将导致renderTriggered调用        {          key: "cart",          target: {            cart: 1          },          type: "set"        }      */    }  }})app.mount('#app')

总结

无论你抉择应用选项API还是 组合API,不仅要晓得要应用哪个生命周期挂钩,而且要晓得为什么要应用它,这一点很重要。

对于许多问题,能够应用多个生命周期钩子。然而最好晓得哪个是最适宜你用例的。无论如何,你都应该好好考虑一下,并有充沛的理由去抉择一个特定的生命周期钩子。

我心愿这能帮忙大家更多地了解生命周期钩子以及如何在大家的我的项目中实现它们。

~完,我是刷碗智,我要去刷碗了,骨的白。


代码部署后可能存在的BUG没法实时晓得,预先为了解决这些BUG,花了大量的工夫进行log 调试,这边顺便给大家举荐一个好用的BUG监控工具 Fundebug。

原文:https://learnvue.co/2020/12/h...

交换

文章每周继续更新,能够微信搜寻「 大迁世界 」第一工夫浏览和催更(比博客早一到两篇哟),本文 GitHub https://github.com/qq449245884/xiaozhi 曾经收录,整顿了很多我的文档,欢送Star和欠缺,大家面试能够参照考点温习,另外关注公众号,后盾回复福利,即可看到福利,你懂的。