vue2自定义类钩子函数

756 阅读1分钟

前言

因为部分字段的值,需要在前置接口发完之后才能取到,在mounted中获取字段值会报错,如果能自定义一个钩子,在接口发送完触发就好了,于是在网上copy了大佬的代码,实现了类钩子,但是小伙伴却表示不太能理解,于是想解释下这段代码。当然了,水平好的建议直接看原文~ 链接

一、如何触发类似mounted的钩子

  mounted() {
    this.$options.afterGetversion();
  },
  afterGetversion() {
    console.log('aaaaaaaaaaaaaaaaaaaaaaaa');
  }

类钩子函数,其实就是和created,mounted同级的方法,可以使用this.$options调用

二、如何获取最外层Vue实例的参数

main.js

const globol = {
  name: "小明",
};
new Vue({
  el: "#app",
  router,
  globol,
});

demo.vue

  created() {
    this[$options.parent.$options.parent...].globol
    
    // 或者
    let options = this.$options
    while(options.parent) {
      options = options.parent.$options
    }
    console.log(options.globol)
  },

优化下写成这样(和vuex等实现类似,需要给每个vue文件都加上)

  created() {
      const options = this.$options;
      if (options.globol) {
        this.myGlobol = options.globol;
      } else if (options.parent && options.parent.globol) {
        this.myGlobol = options.parent.globol;
      }
  },

三、将全局变量改成promise

main.js

    const globolPromise = function() {
        return new Promise((res, rej) => { rej() })
    }
    
    new Vue({
      el: '#app',
      router,
      globolPromise
    })

demo.vue

  created() {
    let options = this.$options
    while(options.parent) {
      options = options.parent.$options
    }
    this.myGlobolPromise = options.globolPromise();
  },
  mounted() {
      this.myGlobolPromise.finally(() => { this.$options.afterGetversion() });
  },
  afterGetversion() { console.log('aaaaaaaaaaaaaaaaaaaaaaaa'); }

四、全量代码

利用全局mixins,将代码全局混入。

customHook.js

function initRestore() {
  const options = this.$options;

  if (options.restore) {
    this.$restore = options.restore;
  } else if (options.parent && options.parent.$restore) {
    this.$restore = options.parent.$restore;
  }
}

/**
 * 给 Vue 实例添加 afterGetversion 钩子。
 * resotore 完成之后调用(无论成功失败)
 */
function initRestored() {
  const { afterGetversion } = this.$options;
  if (afterGetversion && typeof afterGetversion === "function") {
    if (this.$restore) {
      this.$restore.finally(() => afterGetversion.call(this));
    }
  }
}

function getVersion() {
    return new Promise((res, rej) => { rej() })
}

export { initRestore, initRestored, getVersion };

main.js

import { initRestore, initRestored, getVersion } from '@/utils/customHook';
Vue.mixin({ created: initRestore, mounted: initRestored });

const restore = getVersion();
new Vue({
  el: '#app',
  router,
  store,
  i18n: i18n,
  restore,
})

demo.vue

  created() {},
  afterGetversion() {
    // getversion接口发完会自动触发
    console.log('aaaaaaaaaaaaaaaaaaaaaaaa'); 
  }