7 changed files with 98 additions and 31 deletions
@ -1,3 +0,0 @@ |
|||||
div{ |
|
||||
background-color: rebeccapurple; |
|
||||
} |
|
@ -1,15 +1,82 @@ |
|||||
<template> |
<template> |
||||
<div> |
<button @click="onClick" :disabled="isDisabled" :loading="isLoading" type="button" size="small"> |
||||
send |
{{ text }} |
||||
</div> |
</button> |
||||
</template> |
</template> |
||||
|
|
||||
<script setup lang="ts"> |
<script lang="ts" setup> |
||||
|
import { onBeforeUnmount, ref, watchEffect } from "vue" |
||||
|
const props = withDefaults( |
||||
|
defineProps<{ |
||||
|
duration?: number |
||||
|
initText?: string |
||||
|
runText?: string |
||||
|
loadingText?: string |
||||
|
resetText?: string |
||||
|
}>(), |
||||
|
{ |
||||
|
runText: "{%s}s 后重新发送", |
||||
|
initText: "获取验证码", |
||||
|
loadingText: "正在发送", |
||||
|
resetText: "重新获取", |
||||
|
duration: 60, |
||||
|
}, |
||||
|
) |
||||
|
const emits = defineEmits<{ |
||||
|
(event: "update:modelValue", show: boolean): void |
||||
|
(event: "send", start: () => void, done: (isDone: boolean) => void): void |
||||
|
}>() |
||||
|
|
||||
</script> |
const text = ref(props.initText) |
||||
|
const isDisabled = ref(false) |
||||
|
const isLoading = ref(false) |
||||
|
let number = props.duration |
||||
|
let timeID: any |
||||
|
|
||||
|
onBeforeUnmount(() => { |
||||
|
stop() |
||||
|
}) |
||||
|
|
||||
<style> |
function stop() { |
||||
div{ |
clearInterval(timeID) |
||||
color: gold |
number = props.duration |
||||
|
text.value = props.resetText |
||||
|
isLoading.value = false |
||||
|
isDisabled.value = false |
||||
|
emits("update:modelValue", false) |
||||
|
} |
||||
|
//获取格式化 |
||||
|
function getText(second: string | number): string { |
||||
|
return props.runText.replace(/\{([^{]*?)%s(.*?)\}/g, String(second)) |
||||
|
} |
||||
|
function run() { |
||||
|
isLoading.value = false |
||||
|
text.value = getText(number) |
||||
|
clearInterval(timeID) |
||||
|
timeID = setInterval(() => { |
||||
|
number-- |
||||
|
text.value = getText(number) |
||||
|
if (number <= 0) { |
||||
|
stop() |
||||
|
} |
||||
|
}, 1000) |
||||
} |
} |
||||
</style> |
|
||||
|
function onClick() { |
||||
|
emits( |
||||
|
"send", |
||||
|
() => { |
||||
|
isDisabled.value = true |
||||
|
isLoading.value = true |
||||
|
text.value = props.loadingText |
||||
|
}, |
||||
|
(isDone: boolean) => { |
||||
|
if (isDone) { |
||||
|
run() |
||||
|
} else { |
||||
|
stop() |
||||
|
} |
||||
|
}, |
||||
|
) |
||||
|
} |
||||
|
</script> |
||||
|
@ -0,0 +1,11 @@ |
|||||
|
{ |
||||
|
"name": "@princess-ui/hooks", |
||||
|
"version": "1.0.0", |
||||
|
"description": "", |
||||
|
"main": "index.ts", |
||||
|
"module": "index.ts", |
||||
|
"scripts": {}, |
||||
|
"keywords": [], |
||||
|
"author": "", |
||||
|
"license": "ISC" |
||||
|
} |
@ -0,0 +1,5 @@ |
|||||
|
export function useNamespace(text: string) { |
||||
|
return { |
||||
|
|
||||
|
} |
||||
|
} |
Loading…
Reference in new issue