-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvue-get-code.vue
101 lines (94 loc) · 2.41 KB
/
vue-get-code.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
<template>
<span
class="vue-get-code"
:class="[disable && 'disable', enableCountdown && 'enable-countdown']"
@click="click"
>
<slot v-if="!enableCountdown" name="default" :data="{interval, seconds, count}">获取验证码</slot>
<slot v-if="enableCountdown" name="countdown" :data="{interval, seconds}">{{ interval - seconds }}S</slot>
</span>
</template>
<script>
export default {
name: 'VueGetCode',
props: {
getCode: {
required: true,
type: Function
},
interval: {
default: 60,
type: Number
},
// 让外部调用者能控制组件的禁用状态,比如,如果没填手机号码,获取验证码的按钮要禁用
disable: {
default: false,
type: Boolean
}
},
data() {
return {
timer: null,
seconds: 0,
enableCountdown: false,
// 发送验证码的次数
count: 0
}
},
watch: {
disable(newValue) {
// 倒计时正在运行,外部突然禁用了,就清理计时器等状态
if (newValue && this.timer) {
this.reset()
}
}
},
destroyed() {
this.reset()
},
methods: {
click() {
if (this.enableCountdown) return
if (this.disable) return
this.seconds = 0
this.enableCountdown = true
// vue-sfc-cli 对 async await 的支持还有问题,暂时换成 Promise 写法
new Promise((resolve, reject) => {
let result
try {
result = this.getCode() // getCode 可能是同步的,也可能是 Promise 异步函数
} catch (error) {
reject(error)
}
resolve(result)
})
.catch(error => {
this.$emit('getCodeError', error)
this.reset()
})
.then(() => {
this.count++
this.$emit('countdownBegin', this.seconds, this.interval)
this.timer = setInterval(() => {
this.seconds++
if (this.disable) {
this.reset()
return
}
this.$emit('countdownUpdate', this.seconds, this.interval)
if (this.seconds >= this.interval) {
this.$emit('countdownEnd', this.seconds, this.interval)
this.reset()
}
}, 1000)
})
},
reset() {
clearInterval(this.timer)
this.timer = null
this.seconds = 0
this.enableCountdown = false
}
}
}
</script>