Vue纯数字验证码

该验证码为4个数字生成的验证码,亲自验证点击切换,验证码组件Identify.vue可直接复制使用

提示: 该验证码图片缩小后数字经常看不清所以在这里仅仅是实现,没有详细进行实现登陆,仅仅实现了生成验证码,点击验证码后刷新验证码,真正的项目,若验证码图片要求小一点该验证码方式不合适,所以没有进行详细设计

Identify.vue

<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 < 8; 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 < 100; 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>

Login.vue  一下是引用,注意位置

首先是引入验证码组件

import Identify from '@/utils/Identify'

export default {
   components: {
       Identify
  }
}

在表单中引入

    <Row>
        <Col span="24">
          <FormItem prop="yzm">
            <Input type="text" v-model="yzm" placeholder="yzm" />
            <div @click="refreshCode">
              <Identify :identifyCode="identifyCode"></Identify>
            </div>
          </FormItem>
        </Col>
      </Row>

点击触发事件,在方法method中

    // 生成随机数
    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)
    }

 页面首次进入必须将默认的验证码去掉,并刷出新的验证码

  mounted () {
    this.identifyCode = ''
    this.makeCode(this.identifyCodes, 4)
  },

Login.vue登录页全页代码

<template>
  <div>
    <public-header></public-header>
    <hr/>
    <Form ref="login" :model="user" :rules="ruleInline" inline>
      <Row>
        <Col span="24">
          <FormItem prop="account">
            <Input type="text" v-model="user.account" placeholder="Account">
              <Icon type="ios-person-outline" slot="prepend"></Icon>
            </Input>
          </FormItem>
        </Col>
      </Row>
      <Row>
        <Col span="24">
          <FormItem prop="password">
            <Input type="password" v-model="user.password" placeholder="Password">
              <Icon type="ios-lock-outline" slot="prepend"></Icon>
            </Input>
          </FormItem>
        </Col>
      </Row>
      <Row>
        <Col span="24">
          <FormItem prop="yzm">
            <Input type="text" v-model="yzm" placeholder="yzm" />
            <div @click="refreshCode">
              <Identify :identifyCode="identifyCode"></Identify>
            </div>
          </FormItem>
        </Col>
      </Row>
      <Row>
        <Col span="24">
          <FormItem>
            <Button type="primary" @click="handleSubmit('login')">登陆</Button>
            <Button type="primary" @click="back">去首页</Button>
          </FormItem>
        </Col>
      </Row>
    </Form>
    <hr/>
    <public-footer></public-footer>
  </div>
</template>
<script>
import PublicFooter from '@/views/background/publicpages/PublicFooter'
import PublicHeader from '@/views/background/publicpages/PublicHeader'
import Identify from '@/utils/Identify'
import {
  login
} from '@/services/login'
export default {
  name: 'Login',
  components: {
    PublicFooter,
    PublicHeader,
    Identify
  },
  data () {
    return {
      msg: '这个是登录页',
      identifyCodes: '1234567890',
      identifyCode: '',
      user: {
        account: '',
        password: '',
        verifycode: ''
      },
      ruleInline: {
        account: [{
          required: true,
          message: 'Please fill in the account',
          trigger: 'blur'
        }, {
          type: 'string',
          min: 5,
          message: 'The account length cannot be less than 5 bits',
          trigger: 'blur'
        }],
        password: [{
          required: true,
          message: 'Please fill in the password.',
          trigger: 'blur'
        }, {
          type: 'string',
          min: 6,
          message: 'The password length cannot be less than 6 bits',
          trigger: 'blur'
        }],
        yzm: [{
          required: true,
          message: 'Please fill in the yzm.',
          trigger: 'blur'
        }, {
          type: 'string',
          min: 4,
          message: 'The yzm length cannot be less than 4 bits',
          trigger: 'blur'
        }]
      }
    }
  },
  mounted () {
    this.identifyCode = ''
    this.makeCode(this.identifyCodes, 4)
  },
  methods: {
    handleSubmit (name) {
      this.$refs[name].validate((valid) => {
        if (valid) {
          // 配置默认接口地址,封装参数发送,以下注释中的请求也可以
          /* const para = Object.assign({}, this.user)
            setTimeout(() => {
            login(para).then(res => {

            }).catch(() => {
              // 登陆失败操作
            }, 500)
          }) */
          // 带参发送
          setTimeout(() => {
            login({
              account: this.user.account,
              password: this.user.password
            }).then(res => {

            }).catch(() => {
              // 登陆失败操作
            }, 500)
          })
        } else {
          console.log('error submit!!')
          return false
        }
      })
    },
    back () {
      this.$router.push('/')
    },
    // 生成随机数
    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)
    }
  }
}
</script>
<style lang="postcss" scoped>
    body {
        background-color: #ff0000;
    }
</style>

代码生成效果

猜你喜欢

转载自blog.csdn.net/weixin_41996632/article/details/86510542