1. 程式人生 > 程式設計 >vue專案中掃碼支付的實現示例(附demo)

vue專案中掃碼支付的實現示例(附demo)

目錄
  • 需求背景
  • 思路分析
  • UI展示
  • 開始使用
    • 一 編寫支付元件模板
    • 二 支付元件的相關程式碼和說明
  • 附:元件JS完整的原始碼

    需求背景

    市場報告列表展示的報告有兩種型別,一種是免費報告,另一種是付費報告。免費報告使用者可以直接檢視,付費報告需要使用者購買之後才能檢視。

    vue專案中掃碼支付的實現示例(附demo)

    思路分析

    • 點選檢視為付費報告,彈出支付二維碼。
    • 建立訂單,二維碼進行倒計時,其展示5秒後開始監聽支付回撥結果,頻次為五秒一次。
    • 倒計時第一次倒數到0秒,提醒二維碼過期讓使用者點選重新整理二維碼。
    • 繼續倒計時並開始監聽支付回撥結果。
    • 重新整理之後倒數到0秒還沒有監聽到結果則關閉支付彈窗,讓用http://www.cppcns.com
      戶重新發起支付。

    UI展示

    支付彈窗未過期長這樣子喔

    vue專案中掃碼支付的實現示例(附demo)

    支付彈窗過期時長這樣子喔

    vue專案中掃碼支付的實現示例(附demo)

    開始使用

    支付功能作為專案的公共功能,所以我們單獨封裝一個元件,這樣其他模組使用的時候就以子元件的方式引入。

    一 編寫支付元件模板

    下面是模板具體的原始碼,由於樣式不是我們考慮的重點,所以就不展示樣式的程式碼了,根據需要自行新增哈。

    <template>
      <div>
        <el-dialog
          class="dialog-pay"
          title=""
          :visible.sync="dialogVisible"
          :show-close="false"
          @close="handleClosePay"
        >
          <div class="content">
            <p class="tip">{{ pay.title }}</p>
            <p class="tip">
              支付金額:<span class="small">¥</span
       
    ><span class="large">{{ pay.money }}</span> </p> <img class="pic" :style="{ opacity: btnDisabled ? 1 : 0.3 }" :src="pay.url" /> <el-button class="btn" :class="btnDisabled ? 'disabled' : ''" type="primary" :disabled="btnDisabled" @click="handleRe
    freshCode" >{{ btnText }}</el-button > </div> </el-dialog> </div> </template>

    二 支付元件的JS相關程式碼和說明

    1. 監聽支付彈窗是否顯示
    子元件通過props屬性,在子元件中接收父元件傳過來的值。用watch監聽pay.show,只有為true的時候顯示支付彈窗,並且在顯示5秒後開始執行監聽支付結果的方法。

    watch: {
        'pay.show': {
          handler(val) {
            if (val) {
              this.dialogVisible = this.pay.show
              setTimeout(this.handleReportPayNotify(),5000)
            }
          },immediate: true
        }
    },

    2. 二維碼開始倒計時
    二維碼開始進行60秒的倒計時,到0秒提示點選重新整理重新獲取二維碼,繼續開始倒計時,此時如果到0秒則關閉支付彈窗,提示使用者等待時間過長,請重新發起支付。

    handleCountDown() {
      if (this.second == 1) {
        if (this.refresh) {
          this.second = 60
          this.btnDisabled = false
          this.btnText = '點選重新整理重新獲取二維碼'
          if (this.timer) {
            clearInterval客棧(this.timer)
          }
        } else {
          this.$emit('closePay',{ type: 'fail' })
          clearInterval(this.timer)
          this.$message.warning('等待時間過長,請重新發起支付')
        }
      } else {
        this.second--
        this.btnDisabled = true
        this.btnText = `距離二維碼過期剩餘${this.second}秒`
        this.downTimer = setTimeout(() => {
          this.handleCountDown()
        },1000)
      }
    },

    3. 監聽支付彈窗關閉

    handleClosePay() {
      if (this.timer) {
        clearInterval(this.timer)
      }
      if (this.downTimer) {
        clearTimeout(this.downTimer)
      }
      this.$emit('closePay',{ type: 'fail' })
      this.$message.warning('您已取消支付')
    },

    4. 監聽支付回撥結果
    回撥結果有兩種,如果是正常範圍內監聽成功,則執行父元件傳過來的fn,並清除定時器;如果監聽到次數為12的時候還沒有得到相應的結果,則關閉支付彈窗,提示使用者等待時間過長,請重新發起支付,並清除定時器。

    handleReportPayNotify() {
          let num = 0
          this.timer = setInterval(() => {
            num++
            this.pay.fn().then(res => {
              if (res.status == 111111) {
                this.$emit('closePay',{ type: 'succpHDhyess' })
                clearInterval(this.timer)
              }
            })
            if (num == 12) {
              this.$emit('closePay',{ type: 'fail' })
              clearInterval(this.timer)
              this.$message.warning('等待時間過長,請重新發起支付')
            }
          },5000)
        }
    

    5. 支付元件銷燬時清除定時器
    這一步是容易忽略但是也是需要做的,當元件銷燬時將定時器及時的清除掉。

      beforeDestroy() {
        if (this.timer) {
          clearInterval(this.timer)
        }
        if (this.downTimer) {
          clearTimeout(this.downTimer)
        }
      }
    }
    

    附:元件JS完整的原始碼

    <script>
    export default {
      name: 'WechatPay',props: {
        pay: Object
      },data() {
        return {
          dialogVisible: false,btnDisabled: true,btnText: '',second: 60,timer: null,refresh: true
        }
      },watch: {
        'pay.show': {
          handler(val) {
            if (val) {
              this.dialogVisible = this.pay.show
              setTimeout(this.handleReportPayNotify(),immediate: true
        }
      },mounted() {
        this.handleCountDown()
      },methods: {
        /**
         * @descripttion: 重新整理二維碼
         */
        handleRefreshCode() {
          this.$bus.$emit('refreshCode')
          this.handleCountDown()
          this.handleReportPayNotify()
          this.refresh = false
        },/**
         * @descripttion: 二維碼倒計時
         */
        handleCountDown() {
          if (this.second == 1) {
            if (this.refresh) {
              this.second = 60
              this.btnDisabled = false
              this.btnText = '點選重新整理重新獲取二維碼'
              if (this.timer) {
                clearInterval(this.timer)
              }
            } else {
              this.$emit('closePay',{ type: 'fail' })
              clearInterval(this.timer)
              this.$message.warning('等待時間過長,請重新發起支付')
            }
          } else {
            this.second--
            this.btnDisabled = true
            this.btnText = `距離二維碼過期剩餘${this.second}秒`
            this.downTimer = setTimeout(() => {
              this.handleCountDown()
            },1000)
          }
        },/**
         * @descripttion: 監聽支付彈窗關閉
         */
        handleClosePay() {
          if (this.timer) {
            clearInterval(this.timer)
          }
          if (this.downTimer) {
            clearTimeout(this.downTimer)
          }
          this.$emit('closePay',{ type: 'fail' })
          this.$message.warning('您已取消支付')
        },/**
         * @descripttion: 監測支付回撥結果
         */
        handleReportPayNotify() {
          let num = 0
          this.timer = setInterval(() => {
            num++
            this.pay.fn().then(res => {
              if (res.status == 111111) {
                this.$emit('closePay',{ type: 'success' })
                clearInterval(this.timer)
              }
            })
            if (num == 12) {
              this.$emit('closePay',5000)
        }
      },beforeDestroy() {
        if (this.timer) {
          clearInterval(this.timer)
        }
        if (this.downTimer) {
          clearTimeout(this.downTimer)
        }
      }
    }
    </script>
    

    到此這篇關於專案中掃碼支付的實現示例(附demo)的文章就介紹到這了,更多相關vue 掃碼支付內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!