Files
WAI_Project_UNIX/uni_modules/cool-ui/components/cl-loading/cl-loading.uvue
2025-07-21 16:47:04 +08:00

136 lines
2.3 KiB
Plaintext

<template>
<view
class="cl-loading"
:class="[
{
'is-dark': isDark,
'cl-loading--spin': loading,
'!border-primary-500': color == 'primary',
'!border-green-500': color == 'success',
'!border-yellow-500': color == 'warn',
'!border-red-500': color == 'error',
'!border-surface-500': color == 'info',
'!border-surface-700': color == 'dark',
'!border-white': color == 'light',
'!border-surface-300': color == 'disabled',
'!border-r-transparent': true
},
pt.className
]"
:style="{
// #ifdef APP
transform: `rotate(${rotate}deg)`,
// #endif
height: parseRpx(size!),
width: parseRpx(size!),
borderColor: color
}"
v-if="loading"
>
</view>
</template>
<script setup lang="ts">
import { computed, onMounted, ref, watch } from "vue";
import { isDark, parsePt, parseRpx } from "@/cool";
import type { ClIconProps } from "../cl-icon/props";
defineOptions({
name: "cl-loading"
});
// 定义组件属性
const props = defineProps({
// 透传样式
pt: {
type: Object,
default: () => ({})
},
// 是否加载中
loading: {
type: Boolean,
default: true
},
// 图标大小
size: {
type: [Number, String],
default: 24
},
// 图标颜色
color: {
type: String,
default: ""
}
});
// 透传样式类型定义
type PassThrough = {
className?: string;
icon?: ClIconProps;
};
// 解析透传样式
const pt = computed(() => parsePt<PassThrough>(props.pt));
// 旋转角度
const rotate = ref(0);
// 开始旋转动画
function start() {
requestAnimationFrame(() => {
// 增加旋转角度
rotate.value += 1;
// 如果仍在加载中则继续旋转
if (props.loading) {
start();
}
});
}
// 组件挂载后监听loading状态
onMounted(() => {
// #ifdef APP-UVUE
watch(
computed(() => props.loading),
(val: boolean) => {
// 当loading为true时开始旋转
if (val) {
start();
}
},
{
immediate: true
}
);
// #endif
});
</script>
<style lang="scss" scoped>
.cl-loading {
@apply flex flex-row items-center justify-center rounded-full;
@apply border-surface-700 border-solid;
border-width: 2rpx;
&.is-dark {
@apply border-white;
}
// #ifdef H5 || MP
&--spin {
animation: spin 2.5s linear infinite;
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
// #endif
}
</style>