Files
shoot-miniprograms/src/components/SButton.vue

97 lines
1.7 KiB
Vue
Raw Normal View History

2025-05-10 16:57:36 +08:00
<script setup>
2025-06-19 01:55:40 +08:00
import { ref } from "vue";
2025-06-22 15:04:10 +08:00
import { debounce } from "@/util";
2025-05-10 16:57:36 +08:00
const props = defineProps({
width: {
type: String,
default: "calc(100vw - 20px)",
},
rounded: {
type: Number,
default: 10,
},
onClick: {
type: Function,
2025-06-19 01:55:40 +08:00
default: async () => {},
2025-05-10 16:57:36 +08:00
},
2025-05-31 18:39:41 +08:00
disabled: {
type: Boolean,
default: false,
},
2025-06-16 00:30:56 +08:00
backgroundColor: {
type: String,
default: "#fed847",
},
color: {
type: String,
default: "#000",
},
2025-07-29 10:46:37 +08:00
disabledColor:{
type: String,
default: "#757575",
}
2025-05-10 16:57:36 +08:00
});
2025-06-19 01:55:40 +08:00
const loading = ref(false);
2025-06-22 15:04:10 +08:00
const timer = ref(null);
const onBtnClick = debounce(async () => {
2025-06-19 01:55:40 +08:00
if (props.disabled || loading.value) return;
2025-06-22 15:04:10 +08:00
let loadingTimer = null;
loadingTimer = setTimeout(() => {
loading.value = true;
}, 300);
2025-06-19 01:55:40 +08:00
try {
await props.onClick();
} finally {
2025-06-22 15:04:10 +08:00
clearTimeout(loadingTimer);
2025-06-19 01:55:40 +08:00
loading.value = false;
}
2025-06-22 15:04:10 +08:00
});
2025-05-10 16:57:36 +08:00
</script>
<template>
2025-06-15 15:53:57 +08:00
<button
2025-05-26 16:28:13 +08:00
class="sbtn"
2025-06-15 15:53:57 +08:00
hover-class="none"
2025-05-31 18:39:41 +08:00
:style="{
width: width,
borderRadius: rounded + 'px',
2025-07-29 10:46:37 +08:00
backgroundColor: disabled ? disabledColor : backgroundColor,
2025-06-16 00:30:56 +08:00
color,
2025-05-31 18:39:41 +08:00
}"
2025-06-15 15:53:57 +08:00
open-type="getUserInfo"
2025-06-19 01:55:40 +08:00
@click="onBtnClick"
2025-05-10 16:57:36 +08:00
>
2025-06-19 01:55:40 +08:00
<block v-if="!loading">
<slot />
</block>
<block v-else>
<image src="../static/btn-loading.png" mode="widthFix" class="loading" />
</block>
2025-06-15 15:53:57 +08:00
</button>
2025-05-10 16:57:36 +08:00
</template>
<style scoped>
2025-05-26 16:28:13 +08:00
.sbtn {
2025-05-10 16:57:36 +08:00
margin: 0 auto;
2025-06-16 00:30:56 +08:00
height: 44px;
line-height: 44px;
2025-05-10 16:57:36 +08:00
font-weight: bold;
font-size: 15px;
2025-05-26 16:28:13 +08:00
display: flex;
2025-06-19 01:55:40 +08:00
text-align: center;
2025-05-26 16:28:13 +08:00
justify-content: center;
align-items: center;
2025-07-12 16:01:49 +08:00
overflow: initial;
2025-05-10 16:57:36 +08:00
}
2025-06-19 01:55:40 +08:00
.loading {
width: 25px;
height: 25px;
background-blend-mode: darken;
animation: rotate 1s linear infinite;
}
2025-05-10 16:57:36 +08:00
</style>