chore: Optimize loading display
parent
0732a8d853
commit
666371ed67
|
@ -1,97 +1,108 @@
|
|||
<script lang="ts" setup>
|
||||
import { useNamespace } from '@vben-core/toolkit';
|
||||
import type { TimeoutHandle } from '@vben/types';
|
||||
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
interface Props {
|
||||
/**
|
||||
* @zh_CN 最小加载时间
|
||||
* @en_US Minimum loading time
|
||||
*/
|
||||
minLoadingTime?: number;
|
||||
/**
|
||||
* @zh_CN loading状态开启
|
||||
*/
|
||||
spinning: boolean;
|
||||
spinning?: boolean;
|
||||
}
|
||||
|
||||
defineOptions({
|
||||
name: 'Spinner',
|
||||
});
|
||||
|
||||
defineProps<Props>();
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
minLoadingTime: 200,
|
||||
});
|
||||
const startTime = ref(0);
|
||||
const endTime = ref(0);
|
||||
const showSpinner = ref(false);
|
||||
const timer = ref<TimeoutHandle>();
|
||||
|
||||
const { b, e } = useNamespace('spinner');
|
||||
watch(
|
||||
() => props.spinning,
|
||||
(show) => {
|
||||
if (!show) {
|
||||
showSpinner.value = false;
|
||||
clearTimeout(timer.value);
|
||||
return;
|
||||
}
|
||||
startTime.value = performance.now();
|
||||
timer.value = setTimeout(() => {
|
||||
endTime.value = performance.now();
|
||||
|
||||
const loadingTime = endTime.value - startTime.value;
|
||||
|
||||
showSpinner.value = loadingTime > props.minLoadingTime;
|
||||
}, props.minLoadingTime);
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="[b(), !spinning ? 'hidden' : '']"
|
||||
v-if="showSpinner"
|
||||
class="flex-center bg-overlay absolute left-0 top-0 size-full backdrop-blur-sm"
|
||||
>
|
||||
<div :class="e('loader')"></div>
|
||||
<div class="loader relative h-12 w-12"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@vben-core/design/global';
|
||||
|
||||
@include b('spinner') {
|
||||
@keyframes jump-ani {
|
||||
15% {
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
|
||||
25% {
|
||||
transform: translateY(9px) rotate(22.5deg);
|
||||
}
|
||||
|
||||
50% {
|
||||
border-bottom-right-radius: 40px;
|
||||
transform: translateY(18px) scale(1, 0.9) rotate(45deg);
|
||||
}
|
||||
|
||||
75% {
|
||||
transform: translateY(9px) rotate(67.5deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateY(0) rotate(90deg);
|
||||
}
|
||||
@keyframes jump-ani {
|
||||
15% {
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
|
||||
@keyframes shadow-ani {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(1.2, 1);
|
||||
}
|
||||
25% {
|
||||
transform: translateY(9px) rotate(22.5deg);
|
||||
}
|
||||
|
||||
@include e('loader') {
|
||||
position: relative;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
50% {
|
||||
border-bottom-right-radius: 40px;
|
||||
transform: translateY(18px) scale(1, 0.9) rotate(45deg);
|
||||
}
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
top: 60px;
|
||||
left: 0;
|
||||
width: 48px;
|
||||
height: 5px;
|
||||
content: '';
|
||||
background: hsl(var(--color-primary) / 50%);
|
||||
border-radius: 50%;
|
||||
animation: shadow-ani 0.5s linear infinite;
|
||||
}
|
||||
75% {
|
||||
transform: translateY(9px) rotate(67.5deg);
|
||||
}
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
content: '';
|
||||
background: hsl(var(--color-primary));
|
||||
border-radius: 4px;
|
||||
animation: jump-ani 0.5s linear infinite;
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0) rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shadow-ani {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(1.2, 1);
|
||||
}
|
||||
}
|
||||
|
||||
.loader {
|
||||
&::before {
|
||||
@apply bg-primary/50 absolute left-0 top-[60px] h-[5px] w-12 animate-[shadow-ani_0.5s_linear_infinite] rounded-[50%] content-[''];
|
||||
}
|
||||
|
||||
&::after {
|
||||
@apply bg-primary absolute left-0 top-0 h-full w-full animate-[jump-ani_0.5s_linear_infinite] rounded content-[''];
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -20,7 +20,7 @@ fallback:
|
|||
|
||||
widgets:
|
||||
document: Document
|
||||
qa: Q&A
|
||||
qa: FAQ & Help
|
||||
setting: Setting
|
||||
logout-tip: Do you want to log out?
|
||||
view-all: View all messages
|
||||
|
|
|
@ -19,7 +19,7 @@ fallback:
|
|||
|
||||
widgets:
|
||||
document: 文档
|
||||
qa: 问题&建议
|
||||
qa: 问题 & 帮助
|
||||
setting: 设置
|
||||
logout-tip: 是否退出登录?
|
||||
view-all: 查看所有消息
|
||||
|
|
Loading…
Reference in New Issue