项目中需要用到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 就完了