vue實現點擊獲取驗證碼按鈕倒計時時,刷新不重置

前言

           最近博主的前端項目裏有一個需求是點擊獲取驗證碼按鈕後,進入倒計時,重新進入該頁面後,不重置。博主在瞭解需求後,實操了一波,特地記錄實操的代碼供代碼參考使用

前端代碼

<template>
  <el-dialog :visible.sync="dialog" :close-on-click-modal="false" :before-close="cancel" :title="title" append-to-body @open="getCode"
    width="475px" @close="cancel" v-cloak>
    <el-form ref="form" :model="form" :rules="rules" size="small" label-width="88px">
      <el-form-item label="新郵箱" prop="email">
        <el-input v-model="form.email" auto-complete="on" style="width: 200px;" clearable />&nbsp;
        <el-button :loading="codeLoading" type="primary" :disabled="isDisabled" size="small" @click="sendCode">
          {{ buttonName }}
        </el-button>
      </el-form-item>
      <el-form-item label="驗證碼" prop="code">
        <el-input v-model="form.code" style="width: 320px;" clearable />
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="cancel">取消</el-button>
      <el-button :loading="loading" type="primary" @click="doSubmit">確認</el-button>
    </div>
  </el-dialog>
</template>

<script>
  import {
    resetEmail,
    sendEmailCode
  } from '@/apis/email'
  import {
    validedEmail
  } from '@/utils/validate'
  import {
    mapGetters
  } from 'vuex'
  import {
    setItemByKey,
    getItemByKey,
    removeItemByKey
  } from '@/utils/sessionStorageUtils'
  export default {
    computed: {
      ...mapGetters([
        'userInfo'
      ])
    },
    props: {
      email: {
        type: String,
        required: true
      }
    },
    data() {
      const validMail = (rule, value, callback) => {
        if (value === '' || value === null) {
          callback(new Error('新郵箱不能爲空'))
        } else if (value === this.email) {
          callback(new Error('新郵箱不能與舊郵箱相同'))
        } else if (validedEmail(value)) {
          callback()
        } else {
          callback(new Error('郵箱格式錯誤'))
        }
      }
      return {
        loading: false,
        dialog: false,
        title: '修改郵箱',
        form: {
          email: '',
          code: ''
        },
        codeLoading: false,
        buttonName: '獲取驗證碼',
        isDisabled: false,
        time: 60,
        timer: null,
        rules: {
          email: [{
            required: true,
            validator: validMail,
            trigger: 'blur'
          }],
          code: [{
            required: true,
            message: '驗證碼不能爲空',
            trigger: 'blur'
          }]
        }
      }
    },
    methods: {
      cancel() {
        this.resetForm()
      },
      // 獲取驗證碼
      getCode() {
        // 獲取之前點擊獲取郵箱驗證碼時輸入的郵箱
        if (getItemByKey('emain-code-fill-person')) {
          this.form.email = getItemByKey('emain-code-fill-person')
        }
        if (getItemByKey('emain-code-startTime')) {
          // 獲取 點擊獲取驗證時保存的時間毫秒值
          let startDate = getItemByKey('emain-code-startTime')
          // 計算現在時間與startDate的時間差
          let timeDifference = parseInt((new Date().getTime() - startDate) / 1000)
          const _this = this;
          if(timeDifference <= 60) {
            this.time = this.time - timeDifference;
            _this.buttonName = this.time + '秒後重新發送'
            this.isDisabled = true
            this.countdown(_this);
          }
        }
      },
      // 發送驗證碼
      sendCode() {
        if (this.form.email && this.form.email !== this.email) {
          this.codeLoading = true
          this.buttonName = '驗證碼發送中'
          setItemByKey('emain-code-fill-person', this.form.email)
          setItemByKey('emain-code-startTime', new Date().getTime())
          const _this = this
          sendEmailCode(this.form.email).then(res => {
            this.msgSuccess(res.message)
            this.codeLoading = false
            this.isDisabled = true
            this.buttonName = this.time + '秒後重新發送'
            this.countdown(_this);
          }).catch(err => {
            this.resetForm()
            this.codeLoading = false
            console.log(err.response.data.message)
          })

        } else {
          this.warningNotify("請輸入郵箱")
        }
      },
      // 開始倒計時
      countdown(_this) {
        this.timer = setInterval(() => {
          --_this.time
          _this.buttonName = _this.time + '秒後重新發送'
          if (_this.time < 0) {
            _this.buttonName = '重新發送'
            _this.time = 60
            _this.isDisabled = false
            clearInterval(_this.timer)
            removeItemByKey('emain-code-startTime')
          }
        }, 1000)
      },
      doSubmit() {
        this.$refs['form'].validate((valid) => {
          if (valid) {
            this.loading = true
            this.form.username = this.userInfo.username;
            resetEmail(this.form).then(res => {
              this.loading = false
              this.resetForm()
              this.successNotify("郵箱修改成功")
            }).catch(err => {
              this.loading = false
              this.errorNotify(err.response.data.message)
            })
          } else {
            return false
          }
        })
      },
      resetForm() {
        this.dialog = false
        this.$refs['form'].resetFields()
        window.clearInterval(this.timer)
        this.time = 60
        this.buttonName = '獲取驗證碼'
        this.isDisabled = false
        this.form = {
          email: '',
          code: ''
        }
      }
    }
  }
</script>

<style scoped>
  /deep/ .el-dialog__header {
    padding: 20px;
  }

  /deep/ .el-dialog__body {
    padding: 30px 20px 15px 20px;
    border-top: 1px solid #e8e8e8;
    border-bottom: 1px solid #e8e8e8;
  }

  /deep/ .el-dialog__footer {
    padding: 20px;
  }
</style>

本代碼是將獲取郵箱驗證碼抽離成組件的形式。大夥只要關注getCode函數、sendCode函數和countdown函數代碼邏輯即可。

        其核心實現是在點擊發送驗證碼的時候,將當前時間毫秒值保存到sessionStorage中,然後進入倒計時階段,退出當前頁面,重新進入到該頁面時,利用el-dialog組件的open方法回調,調取getCode方法,從sessionStorage中獲取點擊獲取驗證時保存的時間毫秒值,然後與當前時間毫秒值進行比較,如果時間差小於等於60,那麼都還在倒計時的過程中,那麼此時發送驗證碼的按鈕不允許點擊,並且內容爲“xxx秒後重新發送”,直到時間差大於60秒。

用心對待,相信美好東西會如期歸來。ღ( ´・ᴗ・` )比

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章