vue 图形验证码

文章展示了如何在Vue.js中创建一个自定义的验证码组件,该组件能生成包含随机文字、颜色、大小和干扰元素的验证码图片。父组件可以调用并刷新验证码。代码包括模板、脚本和样式部分,涉及数学随机函数、canvas绘图以及响应式属性的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、创建组件

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

      },

      fontSizeMax: {

        type: Number,

        default: 40

      },

      backgroundColorMin: {

        type: Number,

        default: 180

      },

      backgroundColorMax: {

        type: Number,

        default: 240

      },

      colorMin: {

        type: Number,

        default: 50

      },

      colorMax: {

        type: Number,

        default: 160

      },

      lineColorMin: {

        type: Number,

        default: 40

      },

      lineColorMax: {

        type: Number,

        default: 180

      },

      dotColorMin: {

        type: Number,

        default: 0

      },

      dotColorMax: {

        type: Number,

        default: 255

      },

      contentWidth: {

        type: Number,

        default: 112

      },

      contentHeight: {

        type: Number,

        default: 38

      }

    },

    methods: {

      // 生成一个随机数

      randomNum(min, max) {

        return Math.floor(Math.random() * (max - min) + min)

      },

      // 生成一个随机的颜色

      randomColor(min, max) {

        var r = this.randomNum(min, max)

        var g = this.randomNum(min, max)

        var b = this.randomNum(min, max)

        return 'rgb(' + r + ',' + g + ',' + b + ')'

      },

      drawPic() {

        var canvas = document.getElementById('s-canvas')

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

        var x = (i + 1) * (this.contentWidth / (this.identifyCode.length + 1))

        var 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 < 2; 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 < 10; 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>

</style>

2、父组件使用

<template>

  <div class="">

    <div

      class="margin-left-xs tc"

      style="width: 130px; height: 40px;cursor:pointer;"

      @click="refreshCode"

    >

      <validateCode :identifyCode="identifyCode"></validateCode>

    </div>

  </div>

</template>

<script>

import validateCode from "@/components/validateCode/index"; //验证码

export default {

  name: "suggest",

  components: {

    validateCode,

  },

  data() {

    return {

      identifyCodes: "0123456789",

      identifyCode: "",

    };

  },

  created() {},

  mounted() {

    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)

        ];

      }

    },

  },

};

</script>

<style scoped lang="scss"></style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值