<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> 
 |