背景
在一些dialog弹窗提交场景下,有时需要等待提交完成才能继续后面的流程,而且dialog弹窗不能做任何操作,由此需要添加一个覆盖整个dialog弹窗的loading效果,,但是element提供的v-loading指令无法直接作用在dialog上面。
方法一: 自定义一个指令
优点:通用性更强
缺点:自己写的,技术不够,可能会影响性能😅
实现如下:
// directive
app.directive('dialog-loading', {
mounted: (el, binding) => {
nextTick(() => {
const dialogEl = el.querySelector('.el-dialog');
const mask = document.createElement('div');
mask.className = 'dialog-loading-mask';
mask.setAttribute(
'style',
`
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
visibility: hidden;
background-color: rgb(255 255 255 / 90%);
z-index: 9999;
`
);
dialogEl.appendChild(mask);
const app = createApp(Loading);
app.mount(mask);
});
},
updated: (el, binding) => {
const loadingMask = el.querySelector('.dialog-loading-mask');
if (!loadingMask) return;
loadingMask.style.visibility = binding.value ? 'visible' : 'hidden';
},
});// Loading.vue
<template>
<svg class="circular" viewBox="0 0 50 50">
<circle class="path" cx="25" cy="25" r="20" fill="none" />
</svg>
</template>
<style lang="scss" scoped>
.circular {
display: inline;
width: 42px;
height: 42px;
animation: loading-rotate 2s linear infinite;
.path {
animation: loading-dash 1.5s ease-in-out infinite;
stroke-dasharray: 90, 150;
stroke-dashoffset: 0;
stroke-width: 2;
stroke: var(-- el-color-primary);
stroke-linecap: round;
}
}
</style>
使用方法
在el-dialog外面套一层div,在div上添加v-dialog-loading指令,传入loading参数。
方法二:使用Elment Plus提供的ElLoading方法
优点:比较灵活,在每个需要的地方可以单独修改
缺点:每个地方都要单独加,代码量增加,不够通用
实现如下:
<script setup>
import { ElLoading } from 'element-plus'
let loadingInstance
nextTick(() => {
// 获取到最外层的遮罩
const overlay = document.querySelector('.scalling-dialog');
// 获取dialog弹窗的内容部分
const el = overlay?.querySelector('.el-dialog');
// 开启loading
loadingInstance = ElLoading.service({ fullscreen: false, target: el })
// 关闭loading
// loadingInstance.close()
})
</script>
<template>
<el-dialog modal-class="scalling-dialog">xxx</el-dialog>
</template>