小程序初始提交
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
<template>
|
||||
<view
|
||||
ref="loadingRef"
|
||||
class="cl-loading"
|
||||
:class="[
|
||||
{
|
||||
'cl-loading--dark': isDark && color == '',
|
||||
'!border-r-transparent': true
|
||||
},
|
||||
pt.className
|
||||
]"
|
||||
:style="{
|
||||
height: getPx(size!),
|
||||
width: getPx(size!),
|
||||
borderWidth: '1px',
|
||||
borderTopColor: color,
|
||||
borderRightColor: 'transparent',
|
||||
borderBottomColor: color,
|
||||
borderLeftColor: color
|
||||
}"
|
||||
v-if="loading"
|
||||
>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, shallowRef, watch } from "vue";
|
||||
import { createAnimation, ctx, 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 { getPx } = useSize();
|
||||
|
||||
// 透传样式类型定义
|
||||
type PassThrough = {
|
||||
className?: string;
|
||||
icon?: ClIconProps;
|
||||
};
|
||||
|
||||
// 解析透传样式
|
||||
const pt = computed(() => parsePt<PassThrough>(props.pt));
|
||||
|
||||
// 组件引用
|
||||
const loadingRef = shallowRef<UniElement | null>(null);
|
||||
|
||||
// 颜色值
|
||||
const color = computed<string>(() => {
|
||||
if (props.color == "") {
|
||||
return isDark.value ? "#ffffff" : (ctx.color["surface-700"] as string);
|
||||
}
|
||||
|
||||
switch (props.color) {
|
||||
case "primary":
|
||||
return ctx.color["primary-500"] as string;
|
||||
case "success":
|
||||
return "#22c55e";
|
||||
case "warn":
|
||||
return "#eab308";
|
||||
case "error":
|
||||
return "#ef4444";
|
||||
case "info":
|
||||
return "#71717a";
|
||||
case "dark":
|
||||
return "#3f3f46";
|
||||
case "light":
|
||||
return "#ffffff";
|
||||
case "disabled":
|
||||
return "#d4d4d8";
|
||||
default:
|
||||
return props.color;
|
||||
}
|
||||
});
|
||||
|
||||
// 开始旋转动画
|
||||
async function start() {
|
||||
createAnimation(loadingRef.value, {
|
||||
duration: 2500,
|
||||
loop: -1,
|
||||
timingFunction: "linear"
|
||||
})
|
||||
.rotate("0deg", "360deg")
|
||||
.play();
|
||||
}
|
||||
|
||||
// 组件挂载后监听loading状态
|
||||
onMounted(() => {
|
||||
watch(
|
||||
computed(() => props.loading),
|
||||
(val: boolean) => {
|
||||
// 当loading为true时开始旋转
|
||||
if (val) {
|
||||
start();
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
}
|
||||
);
|
||||
});
|
||||
</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;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user