vue 验证码

2021-02-26 09:48:45 浏览数 (1)

一、概述

效果图

二、代码实现

新建test目录,放2个vue文件。

sidentify.vue组件代码:

代码语言:javascript复制
<template>
  <div class="s-canvas">
    <canvas id="s-canvas" :width="contentWidth" :height="contentHeight"></canvas>
  </div>
</template>
<script>
  export default {
    name: 'SIdentify',
    props: {
      identifyCode: {
        type: String,
        default: '1234'
      },
      fontSizeMin: {
        type: Number,
        default: 25
      },
      fontSizeMax: {
        type: Number,
        default: 30
      },
      backgroundColorMin: {
        type: Number,
        default: 255
      },
      backgroundColorMax: {
        type: Number,
        default: 255
      },
      colorMin: {
        type: Number,
        default: 0
      },
      colorMax: {
        type: Number,
        default: 160
      },
      lineColorMin: {
        type: Number,
        default: 100
      },
      lineColorMax: {
        type: Number,
        default: 255
      },
      dotColorMin: {
        type: Number,
        default: 0
      },
      dotColorMax: {
        type: Number,
        default: 255
      },
      contentWidth: {
        type: Number,
        default: 112
      },
      contentHeight: {
        type: Number,
        default: 31
      }
    },
    methods: {
      // 生成一个随机数
      randomNum(min, max) {
        return Math.floor(Math.random() * (max - min)   min)
      },
      // 生成一个随机的颜色
      randomColor(min, max) {
        let r = this.randomNum(min, max)
        let g = this.randomNum(min, max)
        let b = this.randomNum(min, max)
        return 'rgb('   r   ','   g   ','   b   ')'
      },
      drawPic() {
        let canvas = document.getElementById('s-canvas')
        let ctx = canvas.getContext('2d')
        ctx.textBaseline = 'bottom'
        // 绘制背景
        ctx.fillStyle = this.randomColor(this.backgroundColorMin, this.backgroundColorMax)
        ctx.fillRect(0, 0, this.contentWidth, this.contentHeight)
        // 绘制文字
        for (let i = 0; i < this.identifyCode.length; i  ) {
          this.drawText(ctx, this.identifyCode[i], i)
        }
        this.drawLine(ctx)
        this.drawDot(ctx)
      },
      drawText(ctx, txt, i) {
        ctx.fillStyle = this.randomColor(this.colorMin, this.colorMax)
        ctx.font = this.randomNum(this.fontSizeMin, this.fontSizeMax)   'px SimHei'
        let x = (i   1) * (this.contentWidth / (this.identifyCode.length   1))
        let y = this.randomNum(this.fontSizeMax, this.contentHeight - 5)
        var deg = this.randomNum(-45, 45)
        // 修改坐标原点和旋转角度
        ctx.translate(x, y)
        ctx.rotate(deg * Math.PI / 180)
        ctx.fillText(txt, 0, 0)
        // 恢复坐标原点和旋转角度
        ctx.rotate(-deg * Math.PI / 180)
        ctx.translate(-x, -y)
      },
      drawLine(ctx) {
        // 绘制干扰线
        for (let i = 0; i < 5; i  ) {
          ctx.strokeStyle = this.randomColor(this.lineColorMin, this.lineColorMax)
          ctx.beginPath()
          ctx.moveTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight))
          ctx.lineTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight))
          ctx.stroke()
        }
      },
      drawDot(ctx) {
        // 绘制干扰点
        for (let i = 0; i < 80; i  ) {
          ctx.fillStyle = this.randomColor(0, 255)
          ctx.beginPath()
          ctx.arc(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight), 1, 0, 2 * Math.PI)
          ctx.fill()
        }
      }
    },
    watch: {
      identifyCode() {
        this.drawPic()
      }
    },
    mounted() {
      this.drawPic()
    }
  }
</script>
<style scoped>
  .s-canvas {
    height: 38px;

  }
  .s-canvas canvas{
    margin-top: 1px;
    margin-left: 8px;
  }
</style>

说明

test.vue

代码语言:javascript复制
<template>
  <div class="form-group" style="display: flex;">
    <div>
      <span>验证码:</span>
      <input type="text" id="code" v-model="code" class="code" placeholder="请输入验证码"/>
    </div>
    <div class="login-code" @click="refreshCode">
      <!--验证码组件-->
      <s-identify :identifyCode="identifyCode"></s-identify>
    </div>
    <div>
      <button @click="checkCaptcha">验证</button>
    </div>
  </div>

</template>

<script>
  import SIdentify from '../login/sidentify'

  export default {
    components: { SIdentify },
    data() {
      return {
        identifyCodes: '1234567890',
        identifyCode: '',
        code: '',//text框输入的验证码
        tableData: []
      }
    },
    mounted: function() {
      this.identifyCode = ''
      // 初始化验证码
      this.makeCode(this.identifyCodes, 4)
    },
    methods: {
      //验证码
      randomNum(min, max) {
        return Math.floor(Math.random() * (max - min)   min)
      },

      refreshCode() {
        this.identifyCode = ''
        this.makeCode(this.identifyCodes, 4)
      },
      makeCode(o, l) {
        for (let i = 0; i < l; i  ) {
          this.identifyCode  = this.identifyCodes[
            this.randomNum(0, this.identifyCodes.length)
            ]
        }
        console.log("验证码",this.identifyCode)
      },
      // 检查验证码是否正确
      checkCaptcha(){
        if (this.code == ""){
          alert("请输入验证码")
          return false
        }
        if (this.identifyCode != this.code){
          this.code = ''
          this.refreshCode()
          alert("请输入正确的验证码")
          return false
        }
        console.log("验证码正确")
      }
    }
  }
</script>

<style>
  /*验证码样式*/
  .code {
    width: 124px;
    height: 31px;
    border: 1px solid rgba(186, 186, 186, 1);
  }

  .login-code {
    cursor: pointer;
  }
</style>

访问页面,输入正确的验证码,会有提示。

 注意:我在console中,输出了正确的验证码,照着填写即可。

 这个样式,可能不太美观。如果需要用到项目中,可以自行调整样式。

本文参考链接:

https://www.cnblogs.com/web-aqin/p/10796326.html

0 人点赞