/directives/loading/loading.vue loading效果页面(此处使用的antd下面的组件,可自定义)
/directives/loading/loading.js(实现loading组件的插入及销毁)
import Vue from 'vue'
import Loading from './loading.vue'
const Mask = Vue.extend(Loading)
const toggleLoading = (el, binding) => {
if (binding.value) {
Vue.nextTick(() => {
// 控制loading组件显示
el.instance.visible = true
// 插入到目标元素
insertDom(el, el, binding)
})
} else {
el.instance.visible = false
}
}
const insertDom = (parent, el) => {
// 给父元素加个定位,让loading元素定位
el.style.position='relative';
parent.appendChild(el.mask)
}
export default {
bind: function (el, binding, vnode) {
const mask = new Mask({
el: document.createElement('div'),
data() { }
})
el.instance = mask
el.mask = mask.$el
el.maskStyle = {}
binding.value && toggleLoading(el, binding)
},
update: function (el, binding) {
if (binding.oldValue !== binding.value) {
toggleLoading(el, binding)
}
},
unbind: function (el, binding) {
el.style.position='';
el.instance && el.instance.$destroy()
}
}
/directives/loading/index.js(loading指令的注册)
import loading from './loading';
export default {
install(Vue) {
Vue.directive("loading", loading) // 全局loading
}
}
// 引入loading
import loading from './vue-tool/directives/loading'
Vue.use(loading);
我是loading父元素(isLoading为控制loading展示的自定义变量)
/directives/loading/index.vue loading效果页面(此处使用的antd下面的组件,可自定义)
/directives/loading/index.ts(实现loading组件的插入及销毁)
import {createApp, Directive } from 'vue';
import Loading from './index.vue';
export const loading: Directive = {
mounted(el,binding){
const app = createApp(Loading);
const instance = app.mount(document.createElement('div'));
el.instance = instance;
if (binding.value) {
appendEl(el);
}
},
updated(el,binding) {
if (binding.value !== binding.oldValue) {
binding.value ? appendEl(el) : removeEl(el);
}
},
};
// 插入元素
const appendEl = (el) =>{
// 给父元素加个定位,让loading元素定位
el.style.position='relative';
el?.appendChild(el.instance.$el);
};
// 移除元素
const removeEl = (el) =>{
el.style.position='';
// 踩坑:el?.removeChild(el.instance.$el)->直接这样写会报错:Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.(要删除的节点不是此节点的子节点)
// 解决:判断一下是否为此节点的子元素再移除(参考:https://www.freesion.com/article/2620879355/)
let $el = el.instance.$el;
if (el?.contains($el)) {
el?.removeChild($el);
}
};
/directives/index.ts
export * from './loading'
// 循环注册指令
import * as directives from './tool/directives';
Object.keys(directives).forEach(key => {
Vue.directive(key, (directives as { [key: string ]: Directive })[key]);
});
补充:a-spin为antd组件,显示不了的可以把a-spin部分替换为一个简单的loading效果组件,下面提供两种可直接使用的:
1. 效果1
正在加载中... ...
2. 效果2
加载中... ...