| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- <template>
- <view
- class="cl-loading"
- :class="[
- {
- 'cl-loading--dark': isDark && color == '',
- '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: getRpx(size!),
- width: getRpx(size!),
- borderWidth: getRpx(2),
- borderTopColor: color,
- borderRightColor: 'transparent',
- borderBottomColor: color,
- borderLeftColor: color
- }"
- v-if="loading"
- >
- </view>
- </template>
- <script setup lang="ts">
- import { computed, onMounted, ref, watch } from "vue";
- import { isDark, parsePt } from "@/cool";
- import type { ClIconProps } from "../cl-icon/props";
- import { useSize } from "../../hooks";
- 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: ""
- }
- });
- const { getRpx } = useSize();
- // 透传样式类型定义
- 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;
- &--dark {
- border-color: white !important;
- border-right-color: transparent !important;
- }
- // #ifdef H5 || MP
- &--spin {
- animation: spin 2.5s linear infinite;
- }
- @keyframes spin {
- from {
- transform: rotate(0deg);
- }
- to {
- transform: rotate(360deg);
- }
- }
- // #endif
- }
- </style>
|