You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
<script setup lang="ts"> import { ref } from 'vue'
interface FTButton { type?: 'default' | 'primary' | 'info' size?: 'small' | 'default' | 'large' disabled?: boolean loading?: boolean clickHandle?: () => any }
const props = withDefaults(defineProps<FTButton>(), { type: 'default', size: 'default', disabled: false, loading: false, clickHandle: () => {}, })
const isLoading = ref(false)
async function handleClick() { if (!props.clickHandle || isLoading.value) return isLoading.value = true // 进入 loading
try { await props.clickHandle() // 执行异步操作
} finally { isLoading.value = false // 结束 loading
} }
const setLoading = (loading: boolean) => { isLoading.value = loading }
defineExpose({ setLoading, }) </script>
<template> <div class="ft-button" :class="{ 'ft-button-disabled': disabled || isLoading, [`ft-button-${size}`]: true }" @click="handleClick"> <!-- 添加 loading 判断 --> <div v-show="disabled || isLoading" class="my-button-shadow" /> <!-- 添加 loading 判断 --> <div class="my-button" :class="{ [`my-button-${type}`]: true, [`my-button-${size}`]: true, 'button-disabled': disabled || isLoading, // 添加 loading 判断
}" > <el-icon v-if="isLoading" :color="type === 'default' ? '#26509C' : '#fff'"> <!-- 添加 loading 判断 --> <Loading class="rotate-loading" /> <!-- 添加旋转类 --> </el-icon> <div><slot /></div> </div> </div> </template>
<style scoped lang="scss"> .ft-button { position: relative; display: inline-block; margin-right: 10px; } .ft-button-small { margin-right: 5px; } .ft-button-disabled { pointer-events: none; } .my-button-shadow { position: absolute; width: 100%; height: 100%; z-index: 100; } .my-button { height: 30px; padding: 5px 20px; border-radius: 5px; display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: 14px; //width: fit-content;
position: relative; .el-icon { position: absolute; left: 5px; svg { width: 35px; } } } .button-disabled { opacity: 0.5; } .my-button-small { height: 25px; font-size: 12px; padding: 3px 15px; .el-icon { position: absolute; left: 3px; svg { width: 25px; } } } .my-button-default { background: #fff; color: $primary-color; border: 1px solid $primary-color; } .my-button-primary { background: $primary-color; color: #fff; border: 1px solid $primary-color; }
.my-button-info { background: #335AA5; color: #fff; border: 1px solid #335AA5; }
.rotate-loading { animation: spin 1s linear infinite; }
@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } </style>
|