Solutions to issues related to the life cycle of Vue global asynchronous tasks and components

·

9 min read

I don’t know if you have ever encountered such a scenario. The user’s name and gender need to be rendered on the canvas on the page. When you enter for the first time, you must send an asynchronous request in app.vue to get it. You will definitely not get it on the page. You need to monitor the userInfo changes in vuex, find that the data is obtained, and the mounted hook is executed, before you can render the canvas, you need to monitor the two states to be satisfied before you can go to the following logic, but each page is written in this way, obviously too troublesome.

So I wrote a Sao operation, you can register any asynchronous task, and the corresponding hook can be executed automatically when the conditions are met. It can be used in combination with the native hook or used alone. It is convenient for comparison. I hope this solution can help everyone. , Come back and tell me if it's easy to use.

github:github.com/1977474741/vue-custom-hooks

What is vue-custom-hooks?

  • A thing that can customize vue component hooks. You can register global asynchronous tasks and automatically execute related hooks in the page when the conditions are met.
  • Supports the use of created, mounted, etc. with vue's native hooks.
  • Support traditional h5, mpvue, uni-app

What is it for?

Solve the problem of needing to monitor multiple global states in the business page

Let’s have some real scenes

To enter the Mini Program for the first time, users need to log in onLaunch of app.vue to obtain the token and user information, and then save it in the store. Now we are going to make a page, come in and render the user's avatar, nickname, etc. on the canvas. The key point is that two conditions must be met.

Scheme 1. Monitor on the page whether the store has received user information && dom tree rendering is complete.
//Disadvantages: more troublesome, high coupling, the pages used have to monitor the changes of userinfo and the rendering of the dom tree, there are many repetitive codes, which is not conducive to maintenance
data(){
    return{
        //Number of tasks completed
        num: 0
    }
},
computed: {
    userInfo: function(){
        return this.$store.state.userInfo
},
watch:{
    userInfo(newval,oldval){
        //Listen to get user information
        if(newval.nickName){
            this.num++;
            if(this.num == 2){
                //Can render the canvas
                renderCanvas();
            }
        }
    }
},
mounted(){
    //dom rendering completed
    this.num++;
    if(this.num == 2){
        //Can render the canvas
        renderCanvas();
    }
}
Solution 2. Get user information on the page && dom tree rendering is complete.
//Disadvantages: similar to solution 1, the pages used have to write methods for obtaining user information and monitor the rendering of the dom tree
data(){
    return{
        //Number of tasks completed
        num: 0
    }
},
computed: {
    userInfo: function(){
        return this.$store.state.userInfo
},
methods:{
    getUserInfo(cb){
        //Initiate a request to obtain user information
        let userinfo = {nickName:'Zhang San'};
        this.$store.commit('userinfo',userinfo);
        cb()
    }
},
created(){
    this.getUserInfo(()=>{
        this.num++;
        if(this.num == 2){
            //Can render the canvas
            renderCanvas();
        }
    })
},
mounted(){
    //dom rendering completed
    this.num++;
    if(this.num == 2){
        //Can render the canvas
        renderCanvas();
    }
},

Use vue-custom-hooks to achieve the above scenarios

//The first step is to install the plug-in:
npm install vue-custom-hooks

//The second step is to register the plug-in in the entry file:
import CustomHook from'vue-custom-hooks';
Vue.use({
    install(Vue) {
        CustomHook.init(Vue,{
             'UserInfo':{
                name:'UserInfo',
                watchKey:'$store.state.userinfo',
                deep: true,
                onUpdate(val){
                    //userinfo contains nickName, it means the hook is hit
                    return !!val.nickName;
                }
            }
        })
    }
})

//The third step is to use plug-ins in business pages (any page can be used, with low coupling and less repetitive code):
onMountedUserInfo(){
    //Can render the canvas
    renderCanvas();
}

Function description

  • CustomHook.init

    import CustomHook from'vue-custom-hooks';
    CustomHook.init(Vue, diyHooks)
    
  • diyHooks object description

    {
      //1. Register the attribute monitoring hook
      //UserInfo, the single name of the hook, the first letter is capitalized
      'UserInfo':{
          //name, the full name of the hook, it can be the same as the key above if the monitoring attribute is required, it is required
          name:'UserInfo',
          //The name of the attribute to be monitored by watchKey, the attribute monitoring hook mode is required
          watchKey:'$store.state.userinfo',
          //Whether to hit by default, not required
          hit: false,
          //deep Whether to monitor in depth, not required
          deep: true,
          //The callback executed when the onUpdate property is changed is used to determine whether to hit this hook. It is not required. The default value is equivalent to returning!! val
          onUpdate(val){
              //This means that userinfo contains nickName and hits this hook. Note that you cannot return asynchronously
              return !!val.nickName;
          }
      },
    
      //2. Register event listener hook
      //BeforeMount, hook single name, first letter capitalized
      'BeforeMount':{
          //name, the name of the native hook, used to hit this hook, required
          name:'beforeMount',
          //destroy, the opposite hook name, used to cancel the hit, the event listener hook is required
          destroy:'destroyed',
          //Whether to hit by default, not required
          hit: false
      }
    }
    

How to use?

export default {
    name:'Home',
    created(){
        //Data initialization is complete
    },
    mounted(){
        //dom rendering completed
    },
    onCreatedUserInfo(){
        //Data initialization is complete && Obtaining user information is complete
    },
    onMountedUserInfo(){
        //dom rendering completed && access to user information completed
    }
}

Hook usage rules

`on{UserInfo}{BeforeMount}{Login}{Position}...` //All registered hooks can be matched at will, the arrangement order does not affect the execution of the hooks, they are all in && relationship

Registered native hooks

Launch, Created, Load, Attached, Show, Mounted, Ready
//↓↓↓If you need other hooks, you can register by yourself↓↓↓

Demo QR code

left image description here

If you have any good suggestions, please raise issues or pr

If you like, point a star