Custom Hooks make writing Vue3 easier!

H ʊk: Hook

Hooks are undefined in the front-end domain. In JS, Hooks are callback, event-driven, integrate and define reusable methods

Some reusable methods hang like hooks, which can be introduced and called at any time to achieve the goal of high cohesion and low coupling. – the official documentation for Vue3 does not explicitly state what Hooks are but they are used.

Why custom hooks for Vue3? :

The deeper question is why Vue3 is better than Vue2! I believe many students have read other articles: no outbound call performance is greatly improved, in fact, the coding experience is Vue3’s advantage ** the introduction of Compoosition Api (to solve the strong coupling of Option Api in the case of large code volume) ** let developers have a better development experience.

Personal thoughts: But these so-called improvement of development experience is the need for developers to constantly learn to develop good coding habits, also Vue3 write Compoosition Api some people can write like poetry, some people can write like Shite (sincerely hope that every developer has a keen heart for technology, do not develop for the sake of development, Predecessors write xiang let posterity taste! Sorry for the recent maintenance of the old project too much feeling)

Writing Vue3 please get rid of the thought of Vue2 mindless this:

Many students have formed the habit of writing this without thinking in the Option Api of Vue2. After coming to the Composition Api of Vue3, they still habitually want to use this. Some even introduce getCurrentInstance in order to write this! It’s not necessary!

One of the advantages of Composition APIS is to get rid of the strong coupling caused by mindless this, where functions intermingle with this, and variables and methods are mixed up in various methods.

A component defines a large number of variations and methods. Methods are nested and share variables with each other. To maintain such code, we need to cut back and forth between methos, data and template. Option Api is very simple and clear when the code volume and function are small, but when the code volume is large, the function is complex, I believe that the review code will have a headache.

In the case of components with complex functions and A large amount of code, we cooperated with custom Hooks to write the code in functional blocks, and define and invoke the response variables and methods together. In this way, we only need to pay attention to the code under the function block A in the later stage of modifying function A. There is no need to focus on methos and data like Vue2 in the Option Api.

Let’s review some giFs **Composition ApiGood! **

Thanks for the GIF, the advantages and disadvantages of Composition Api VS Option Api are clearly shown in the animation!

Option ApiToo little code is fine, too much code leads to high coupling!

Note: The Vue2 Option Api is written above. One component contains data, methos, computed and watch. The same function needs to be written on these functions separately. Once the code volume is large and the functions are complex, each function is written separately, and data, Methos, computed and Watch all need to be cut back and forth during maintenance. On the contrary, they are too scattered and highly coupled.

Composition ApiThe decouplingVue2 Option ApiAchieve low coupling and high cohesion

Description: In the case of Composition Api, in the case of components with complex functions and A large amount of code, we will coordinate with custom Hook to write the code according to functions, and define and call variables and methods together. For example, responsive variables and methods are integrated in function A, and we only need to change the code in function module A in the later maintenance. Unlike Vue2, the Option Api needs to focus on both logically dispersed Methos and data.

So custom Hook write Vue3 must master! It all embodies the idea of low coupling and high cohesion of Vue3 Composition Api! I’ve looked at the official documentation and the open source Admin template and it uses a lot of custom Hooks!

Define Vue3’s custom Hook boldly:

While custom Hooks are not officially identified or defined, they are used everywhere;

In the form of functions, some reusable methods are suspended like hooks, which can be introduced and called at any time to achieve the goal of high cohesion and low coupling;

  1. Extract reusable functionality into external JS files

  2. The function name/file name starts with use, for example, useXX

  3. Const {nameRef, Fn} = useXX()

    Destruct the variables and methods of custom hooks in the setup function

Example:

Simple addition and subtraction, separating addition and subtraction into 2 custom Hooks, and passing reactive data to each other

  • Addition function -Hook
import { ref, watch } from 'vue';
const useAdd= ({ num1, num2 }) = >{
    const addNum = ref(0)
    watch([num1, num2], ([num1, num2]) = > {
        addFn(num1, num2)
    })
    const addFn = (num1, num2) = > {
        addNum.value = num1 + num2
    }
    return {
        addNum,
        addFn
    }
}
export default useAdd
Copy the code
  • Subtraction function -Hook
// Subtraction function -hook
import { ref, watch } from 'vue';
export function useSub  ({ num1, num2 }){
    const subNum = ref(0)
    watch([num1, num2], ([num1, num2]) = > {
        subFn(num1, num2)
    })
    const subFn = (num1, num2) = > {
        subNum.value = num1 - num2
    }
    return {
        subNum,
        subFn
    }
}
Copy the code
  • Compute components by addition and subtraction
<template>
    <div>
        num1:<input v-model.number="num1" style="width:100px" />
        <br />
        num2:<input v-model.number="num2" style="width:100px" />
    </div>
    <span>Add equals :{{addNum}}</span>
    <br />
    <span>Subtraction equals :{{subNum}}</span>
</template>
​
<script setup>
import { ref } from 'vue'
import useAdd from './useAdd.js'     // Introduce automatic hooks
import { useSub } from './useSub.js' // Introduce automatic hooksconst num1 = ref(2)
const num2 = ref(1)
// Add function - custom Hook (expose reactive variable or method form)
const { addNum, addFn } = useAdd({ num1, num2 })
addFn(num1.value, num2.value)
// Subtraction function - custom Hook (expose reactive variable or method form)
const { subNum, subFn } = useSub({ num1, num2 })
subFn(num1.value, num2.value)
</script>
​
Copy the code

To relearn the relationship between Vue3 custom Hooks and Vue2 era mixins:

Mixins fall short In Vue 2, mixins are the primary tool for abstracting parts of component logic into reusable blocks. However, they have several problems: 1. Mixins are prone to conflicts: Since every Mixin's property is merged into the same component, you still need to know about every other feature in order to avoid property name conflicts. 2. Reusability is limited: Mixins cannot be passed any parameters to change their logic, which reduces their flexibility in abstract logic.Copy the code

The above paragraph is the content of Vue3 official document, which can be summarized and supplemented as follows:

1, Mixin is difficult to trace the methods and attributes! Vue3 custom Hooks do

Vue3 custom Hooks that explicitly expose responsive variables or methods when referenced:

Const {nameRef, Fn} = useXX()

  • Mixins

    export default {
      mixins: [ a, b, c, d, e, f, g ], // A component can be mixed with various functional mixins
      mounted() {
        console.log(this.name)  // Which mixin does this name come from?}}Copy the code

    Mixins are confused without knowing which Mixin file the attribute comes from, which makes later maintenance difficult

  • Vue3 custom Hooks

    // Add function - custom Hook (expose reactive variable or method form)
    const { addNum, addFn } = useAdd({ num1, num2 })
    addFn(num1.value, num2.value)
    // Subtraction function - custom Hook (expose reactive variable or method form)
    const { subNum, subFn } = useSub({ num1, num2 })
    subFn(num1.value, num2.value)
    Copy the code

    It is easy to see the reactive variables and methods that are explicitly exposed by each Hooks

You cannot pass parameters to mixins to change logic, but Vue3 custom Hooks do:

Vue3 custom Hooks have the flexibility to change their logic by passing any parameters, not limited to exposed variables of other Hooks

  • Mixins
export default {
  mixins: [ addMixin, subMixin], // Add and subtract mixins in components
  mounted(){
      this.add(num1,num2) // Call the add method inside addMixin
      this.sub(num1,num2) // Call the sub method inside subMixin}}Copy the code

You can pass parameters by calling mixins’ internal methods, but you cannot pass parameters directly to mixins because mixins are not exposed as functions and do not pass parameters

  • Vue3 custom Hook

    Add an average Hook to the above example

    // Average function -hook
    import { ref, watch } from "vue";
    export function useAverage(addNum) {
      const averageNum = ref(0);
      watch(addNum, (addNum) = > {
        averageFn(addNum);
      });
      const averageFn = (addNum) = > {
        averageNum.value = addNum / 2;
      };
      return {
        averageNum,
        averageFn,
      };
    }
    Copy the code

    In the component

    / / components
    // Add function - custom Hook (expose reactive variable or method form)
    const { addNum, addFn } = useAdd({ num1, num2 })
    addFn(num1.value, num2.value)// active call, return latest addNum
    // Average functionality - custom Hook- Hook passes in parameter values to other Hook exposed variables
    const { averageNum, averageFn} = useAverage(addNum)
    averageFn(addNum.value)
    Copy the code

    Vue3 custom Hooks give Vue3 the flexibility to change its logic by passing any parameters that are not limited to exposed variables of other Hooks. This increases Vue3’s flexibility with abstract logic.

3. Mixin variables with the same name will be overwritten. Vue3 custom hooks can rename variables with the same name when introduced

  • Mixins

    export default {
      mixins: [ addMixin, subMixin], // Add and subtract mixins in components
      mounted(){
          this.add(num1,num2) // Call the add method inside the addition addMixin
          this.sub(num1,num2) // Call the sub method inside subMixin}}Copy the code

    If this.add(num1,num2) and this.sub(num1,num2) return totalNum with the same name, since JS is single threaded, the later ones will override the previous ones

  • Vue3 custom Hooks

    // Add function - custom Hook (expose reactive variable or method form)
    const { totalNum:addNum, addFn } = useAdd({ num1, num2 })
    addFn(num1.value, num2.value)
    // Subtraction function - custom Hook (expose reactive variable or method form)
    const { totalNum:subNum, subFn } = useSub({ num1, num2 })
    subFn(num1.value, num2.value)
    Copy the code

    In Vue3 custom Hooks, although both addition and subtraction Hooks return totalNum, variables are easily renamed using ES6 object destruction

Conclusion:

Option Api of Vue2 era, Data, Methos, Watch….. Write separately, this is fragmented and scattered, the code is easy to high coupling, maintenance switching back and forth code is tedious!

Vue3 Era Composition Api for high cohesion and low coupling by using Hooks and custom Hooks to block fragmented, responsive variables and methods into functional chunks

Vue3 custom Hooks are function scoped on components, vue2-era Mixins are global scoped on components. The global scope is sometimes uncontrollable, just as variables like var and let declare keywords, const and let are modifications of var. Composition Api is a correction to Vue2 era Option Api’s high coupling and ubiquitous This black box. Vue3 custom Hooks are an improvement.

Mixins and custom hooks are compared, one is the embodiment of the Option Api, the other is the Composition Api. If you understand the idea of high cohesion and low coupling, you can understand why Vue3 uses Composition APIS and makes code stronger with various custom Hooks. Write code like poetry. Instead of writing shit.

Finally, thank you again for your GIF!

If you think it’s ok, don’t be stingy with a thumbs up!