123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- <template>
- <view class="tn-code-class tn-code">
-
- </view>
- </template>
- <script>
- export default {
- name: 'tn-verification-code',
- props: {
- // 倒计时总秒数
- seconds: {
- type: Number,
- default: 60
- },
- // 开始时提示文字
- startText: {
- type: String,
- default: '获取验证码'
- },
- // 倒计时提示文字
- countDownText: {
- type: String,
- default: 's秒后重新获取'
- },
- // 结束时提示文字
- endText: {
- type: String,
- default: '重新获取'
- },
- // 是否在H5刷新或各端返回再进入时继续倒计时
- keepRunning: {
- type: Boolean,
- default: false
- },
- // 为了区分多个页面,或者一个页面多个倒计时组件本地存储的继续倒计时变了
- uniqueKey: {
- type: String,
- default: ''
- }
- },
- data() {
- return {
- timer: null,
- secNum: this.seconds,
- // 是否可以执行验证码操作
- canGetCode: true
- }
- },
- watch: {
- seconds: {
- handler(n) {
- this.secNum = n
- },
- immediate: true
- }
- },
- mounted() {
- this.checkKeepRunning()
- },
- beforeDestroy() {
- this.setTimeToStorage()
- if (this.timer) {
- clearInterval(this.timer)
- this.timer = null
- }
- },
- methods: {
- // 检查是否继续运行
- checkKeepRunning() {
- // 获取上一次退出页面时的时间戳,如果没有上次保存,该值为空
- let lastTimestamp = Number(uni.getStorageSync(this.uniqueKey + '_$tCountDownTimestamp'))
- if (!lastTimestamp) return this.changeEvent(this.startText)
- // 当前秒的时间戳
- // + new Date() 相当于 new Date().getTime()
- let nowTimestamp = Math.floor((+ new Date()) / 1000)
- // 判断当前的时间戳,是否小于上一次的设定结束的时间,提前于结束的时间戳
- if (this.keepRunning && lastTimestamp && lastTimestamp > nowTimestamp) {
- // 剩余尚未执行完倒计时秒数
- this.secNum = lastTimestamp - nowTimestamp
- // 清除本地保存的变量
- uni.removeStorageSync(this.uniqueKey + '_$tCountDownTimestamp')
- // 开始倒计时
- this.start()
- } else {
- // 如果不存在需要继续上一次的倒计时,执行正常的逻辑
- this.changeEvent(this.startText);
- }
- },
- // 开始倒计时
- start() {
- // 防止快速点击获取验证码按钮导致产生多个定时器导致混乱
- if (this.timer) {
- clearInterval(this.timer)
- this.timer = null
- }
- this.$emit('start')
- this.canGetCode = false
-
- this.changeEvent(this.countDownText.replace(/s|S/, this.secNum))
- this.setTimeToStorage()
- this.timer = setInterval(() => {
- if (--this.secNum) {
- this.changeEvent(this.countDownText.replace(/s|S/, this.secNum))
- } else {
- // 倒计时结束,清空定时器、重置提示信息
- this.reset()
- this.$emit('end')
- }
- }, 1000)
- },
- // 重置倒计时
- reset() {
- this.canGetCode = true
- if (this.timer) {
- clearInterval(this.timer)
- this.timer = null
- }
- this.secNum = this.seconds
- this.changeEvent(this.endText)
- },
- // 倒计时改变事件
- changeEvent(text) {
- this.$emit('change', text)
- },
- // 保存当前时间戳
- // 防止倒计时尚未结束,H5刷新或者各端的右上角返回上一页再进来
- setTimeToStorage() {
- if (!this.keepRunning ||!this.timer) return
- // 记录当前的时间戳,为了下次进入页面,如果还在倒计时内的话,继续倒计时
- // 倒计时尚未结束,结果大于0;倒计时已经开始,就会小于初始值,如果等于初始值,说明没有开始倒计时,无需处理
- if (this.secNum > 0 && this.secNum <= this.seconds) {
- let nowTimestamp = Math.floor((+ new Date()) / 1000)
- // 保存本次倒计时结束时候的时间戳
- uni.setStorageSync(this.uniqueKey + '_$tCountDownTimestamp', nowTimestamp + this.secNum)
- }
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .tn-code {
- width: 0;
- height: 0;
- position: fixed;
- z-index: -1;
- }
- </style>
|