By Michael Thiessen

Click “like” to see, wechat search ** [big move the world],B station pay attention to [front-end small wisdom] ** this does not have a big factory background, but has a positive attitude. In this paper, making github.com/qq449245884… Has been included, the article has been categorized, also organized a lot of my documentation, and tutorial materials.

Recently open source a Vue component, is not perfect, welcome everyone to improve it, also hope you can give a star support, thank you.

Making address:Github.com/qq449245884…

Lifecycle hooks in Vue2 and Vue3 work very similarly, we can still access the same hooks, and we want to use them for the same scenarios.

If the project uses the Options API, there is no need to change any code because Vue3 is compatible with previous versions.

Of course, we used Vue3 to use its composite API, which accesses these hooks in a slightly different way and is particularly useful in larger Vue projects.

Main contents of this paper:

  1. What are the Vue lifecycle hooks
  2. Use Vue lifecycle hooks in the options API
  3. Use Vue 3 lifecycle hooks in the composite API
  4. Update Vue2’s lifecycle hook code to Vue3
  5. Take a look at each lifecycle hook in Vue 2 and Vue 3
  6. create
  7. mount
  8. update
  9. uninstall
  10. The activation
  11. New debug hooks in Vue 3

What are the Vue lifecycle hooks

First, take a look at the diagram of Vue 3 lifecycle hooks in the Option API and composition API. This will give us a better understanding before we get into the details.

In essence, each major Vue lifecycle event is split into two hooks that are called before and after the event. There are four main events (eight main hooks) in a Vue application.

  • Create – Performed when the component is created
  • Mount – Performed when the DOM is mounted
  • Update – Performed when the response data is modified
  • Destroy – Runs immediately before the element is destroyed

inOption APIVue lifecycle hooks are used in

Using the options API, lifecycle hooks are options that are exposed on Vue instances. We don’t need to import anything, just call the method and write code for the lifecycle hook.

For example, suppose we want to access mounted() and updated() lifecycle hooks:

// option API <script> export default {mounted() {console.log('mounted! ') }, updated() { console.log('updated! ') } } </script>Copy the code

inCombination of the APIVue 3 lifecycle hooks are used in

In the composite API, we need to import the lifecycle hooks into the project before we can use them, which helps keep the project lightweight.

Import {onMounted} from 'vue'Copy the code

In addition to beforecate and Created (which are replaced by the Setup method itself), the API lifecycle hooks we can access in the setup method have nine options:

  • OnBeforeMount — Called before the mount begins: The associated render function is called for the first time.

  • OnMounted – called when the component is mounted

  • OnBeforeUpdate – Called when data is updated, before the virtual DOM is patched. This is a good place to access the existing DOM before updating, such as manually removing event listeners that have been added.

  • OnUpdated – This hook is called after the virtual DOM is re-rendered and patched due to data changes.

  • OnBeforeUnmount – called before unmounting a component instance. At this stage, the instance is still perfectly normal.

  • OnUnmounted – called after the component instance is unmounted. When this hook is called, all directives of the component instance are unbound, all event listeners are removed, and all child component instances are unloaded.

  • OnActivated – called when activated by a component cached by keep-alive.

  • OnDeactivated – called when a component that is cached by keep-alive is disabled.

  • OnErrorCaptured – Called when an error is caught from a descendant component. The hook receives three parameters: the error object, the component instance where the error occurred, and a string containing information about the source of the error. This hook can return false to prevent further propagation of the error.

Use Cases:

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

Update Vue2’s lifecycle hook code to Vue3

The lifecycle mapping from Vue2 to Vue3 is obtained directly from the Vue3 Composition API document:

  • BeforeCreate -> Use setup()

  • Created -> Setup ()

  • beforeMount -> onBeforeMount

  • mounted -> onMounted

  • beforeUpdate -> onBeforeUpdate

  • updated -> onUpdated

  • beforeDestroy -> onBeforeUnmount

  • destroyed -> onUnmounted

  • errorCaptured -> onErrorCaptured

Learn more about each lifecycle hook

We now know two important things:

  • Different lifecycle hooks that we can use
  • How do you use them in option apis and composition apis

Let’s drill down to see how each lifecycle hook is used, and we can write specific code in each hook to test the differences between the Options API and Composition API.

BeforeCreate () — Option API

Because the hook created is the thing that initializes all the response data and events, beforeCreate cannot access any of the response data and events for the component.

Take the following code block for example:

// option API export default {data() {return {val: 'hello'}}, beforeCreate() {console.log('Value of val is: ' + this.val) } }Copy the code

The output value of val is undefined because the data has not been initialized and we cannot call component methods from there.

If you want to see a complete list of available content, it is recommended to just run console.log(this) to view the initialized content. This is also useful in other hooks when using the option API.

Created () – Option API

If we want to access component data and events during component creation, we can replace the above beforeCreate with created.

// option API export default {data() {return {val: 'hello'}}, created() {console.log('Value of val is: ' + this.val) } }Copy the code

The output is Value of val is: hello because we have initialized the data.

The created approach is useful when dealing with read/write response data. For example, if you want to make an API call and then store the value, you can do so here.

It is better to do this here than in Mounted, as it occurs during Vue synchronization initialization and we need to perform all data read/write operations.

What about the creation hooks for the composition API?

For Vue3 lifecycle hooks using the composite API, replace beforecate and Created with the setup() method. This means that any code you put in these methods is now only in the Setup methods.

// AP import {ref} from 'vue' export default {setup() {const val = ref('hello') console.log('Value of val is: ' + val.value) return { val } } }Copy the code

beforeMount() and onBeforeMount()

Called before the component DOM is actually rendered and installed. In this step, the root element does not yet exist. In the options API, you can access it using this.$els. In the composition API, in order to do this, ref must be used on the root element.

// 选项 API
export default {
   beforeMount() {
     console.log(this.$el)
   }
 }
Copy the code

Use ref in composite apis:

<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) } }Copy the code

Because app.$el has not yet been created, the output will be undefined.

mounted() and onMounted()

Called after the first rendering of the component, this element is now available, allowing direct DOM access

Similarly, in the options API, we can use this.$el to access our DOM, and in the composite API, we need to use refs to access the DOM in the Vue lifecycle hooks.

import { ref, OnMounted} from 'vue' export default {setup() {/* / const root = ref(null) onMounted(() => { Console. log(root.value)}) return {root}}, mounted() {/* API */ console.log(this.$el)}}Copy the code

beforeUpdate() and onBeforeUpdate()

Called when data is updated and occurs before the virtual DOM is patched. This is a good place to access the existing DOM before updating, such as manually removing event listeners that have been added.

BeforeUpdate is useful for tracking the number of edits to components and even the actions that create undo functionality.

updated() and onUpdated()

When the DOM is updated, the updated method is called.

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

Option API mode:

 export default {
   data() {
      return {
        val: 0
      }
   },
   beforeUpdate() {
      console.log("beforeUpdate() val: " + this.val)
   },
   updated() {
      console.log("updated() val: " + this.val
   }
 } 
Copy the code

Ways to combine apis:

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
     }
   }
 }
Copy the code

These methods are useful, but for more scenarios, we need to use the Watch method to detect these data changes. Watch works because it gives the old and new values of the changed data.

Another option is to use computed attributes to change state based on the element.

BeforeUnmount () and onBeforeUnmounted ()

Called before the component instance is unloaded. At this stage, the instance is still perfectly normal.

An example of removing an event listener in the Options API is shown below.

// API export default {console.log('mount') window.addeventListener ('resize', this.somemethod); // API export default {console.log('mount') window.addeventListener ('resize', this.somemethod); }, beforeUnmount() { console.log('unmount') window.removeEventListener('resize', this.someMethod); }, methods: { someMethod() { // do smth } } }Copy the code
// API import {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); }}})Copy the code

One way to do this in practice is in Vite, VUE-CLI, or any development environment that supports hot overloading, when you update the code, some components will uninstall and install themselves.

Unmounted () and onUnmounted ()

Called after the component instance is unloaded. When this hook is called, all directives of the component instance are unbound, all event listeners are removed, and all child component instances are unloaded.

Import {onUnmounted} from 'vue' export default {setup () {/* onUnmounted() => {console.log('unmounted') })}, unmounted() {/* option API */ console.log('unmounted')}}Copy the code

activated() and onActivated()

Called when activated by a component cached by keep-alive.

For example, if we use the Keep-alive component to manage different TAB views, the current TAB will run the Activated hook every time we switch between tabs.

Suppose we use the keep-alive wrapper for the following dynamic components.

<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 () {/* setup API */ const tabName = ref('Tab1') return {tabName}} </script>Copy the code

Inside the Tab1.vue component, we can access the Activated hook like this.

<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>Copy the code

Deactivated () and onDeactivated ()

Called when a component cached by keep-alive is disabled.

This hook is useful in use cases such as saving user data and triggering animations when a particular view loses focus.

import { onActivated, onDeactivated } from 'vue'

export default {
  setup() {
    onActivated(() => {
       console.log('Tab 1 Activated')
    })

    onDeactivated(() => {
       console.log('Tab 1 Deactivated')
    })
  }
}

Copy the code

Now, as we switch between tabs, the state of each dynamic component will be cached and saved.

Vue3 debug hooks

Vue3 gives us two hooks that can be used for debugging purposes.

  1. onRenderTracked
  2. onRenderTriggered

Both events have a Debugger event that tells you which action tracks the component and the target object and key for that action.

onRenderTracked

Called when tracking the virtual DOM is re-rendered. The hook receives a Debugger event as an argument. This event tells you which action tracks the component and the target object and key for that action.

<div id="app">
  <button v-on:click="addToCart">Add to cart</button>
  <p>Cart({{ cart }})</p>
</div>
Copy the code
const app = Vue.createApp({ data() { return { cart: 0}}, renderTracked({key, target, type}) {console.log({key, target, type}) /* This is recorded when the component is first rendered: {key: "cart", target: { cart: 0 }, type: "get" } */ }, methods: { addToCart() { this.cart += 1 } } }) app.mount('#app')Copy the code

renderTracked

When the virtual DOM is rerendered to triggered.Similarly to renderTracked, receives a Debugger event as an argument. This event tells you what action triggered the rerender, as well as the target object and key for that action.

Usage:

<div id="app">
  <button v-on:click="addToCart">Add to cart</button>
  <p>Cart({{ cart }})</p>
</div>
Copy the code
const app = Vue.createApp({ data() { return { cart: 0 } }, renderTriggered({ key, target, type }) { console.log({ key, target, type }) }, methods: {addToCart() {this.cart += 1 /* This will cause renderTriggered calls {key: "cart", target: {cart: 1}, type: "set" } */ } } }) app.mount('#app')Copy the code

conclusion

Whether you choose to use the option API or the composite API, it is important to know not only which lifecycle hook to use, but also why.

For many problems, you can use multiple lifecycle hooks. But it’s good to know which is best for your use case. Either way, you should think about it and have good reason to choose a particular lifecycle hook.

I hope this has helped you understand more about lifecycle hooks and how to implement them in your projects.

~ finish, I am brush bowl wisdom, I am going to brush bowl, bone of white.


The bugs that may exist after code deployment cannot be known in real time. In order to solve these bugs, I spent a lot of time on log debugging. Incidentally, I recommend a good BUG monitoring tool for youFundebug.

Original text: learnvue co / 2020/12 / how…

communication

This article is updated every week, you can search wechat “big move the world” for the first time to read and urge more (one or two earlier than the blog hey), this article GitHub github.com/qq449245884… It has been included and sorted out a lot of my documents. Welcome Star and perfect. You can refer to the examination points for review in the interview.