开发全局组件

210 阅读1分钟

项目中需要用到loading组件,不需要用到element的时候,引入整个element只用loading实在太。。

Vue.extend

展示一个最简单的全局 loading组件
  • 先写一个 loading 组件,定义一个 show 之类的控制展示变量
  • 通过 Vue.extend 将组件转换为全局组件
import loading from "./Loading.vue";

let instance = null;

export default {
  install(Vue) {
    if (!instance) {
      let loadingComponents = Vue.extend(loading);
      instance = new loadingComponents({
        el: document.createElement("div")
      });
      document.body.appendChild(instance.$el);
    }
    instance.show = false;
    // 组件方法
    let customMethods = {
      show() {
        instance.show = true;
      },
      hide() {
        instance.show = false;
      }
    };
    Vue.$loading = customMethods;
    // 把组件挂载到vue.prototype上
    Vue.prototype.$loading = Vue.$loading;
  }
};
  • 最后main上引入使用就行了

this.$loading实现了,但是元素节点上的 v-loading 呢?

Vue.directive

  • 定义一个loading的指令
import Vue from 'vue'
import Loading from './Loading.vue'
// 使用 Vue.extend构造组件子类
const loadingComponents = Vue.extend(Loading)

Vue.directive('loading', {
    // bind:初始化设置 
    // @param {*} el 指令要绑定的元素
    // @param {*} binding 指令传入的信息
    // @param {*} vnode VUE编译生成的虚拟节点
    bind(el, binding) {
        const instance = new loadingComponents({
          el: document.createElement('div'),
          data: {}
        })
        el.appendChild(instance.$el)
        el.instance = instance
        Vue.nextTick(() => {
          el.instance.show = binding.value
        })
    },
    // inserted:被绑定的元素插入父节点的时候调用
    inserted() {},
    // update:被绑定与元素所在模板更新时调用,而且无论绑定值是否有变化,通过比较更新前后的绑定值,忽略不必要的模板更新
    // @param {*} el
    // @param {*} binding
    update(el, binding) {
        // 通过对比值的变化判断loading是否显示
        if (binding.oldValue !== binding.value) {
          el.instance.show = binding.value
        }
    },
    // componentUpdate:被绑定的元素所在模板完成一次更新更新周期的时候调用
    componentUpdate() {},
    // unbind: 只调用一次,指令月元素解绑的时候调用
    // @param {*} el
    unbind(el) {
        const mask = el.instance.$el
        if (mask.parentNode) {
          mask.parentNode.removeChild(mask)
        }
        el.instance.$destroy()
        el.instance = undefined
    }
})
  • 最后元素上v-loading 就完了