vue 随机动态验证码

<el-form-item prop="phoneCode" label="验证码">
  <el-input
    ref="phoneCode"
    v-model="loginForm.phoneCode"
    placeholder="请输入验证码"
    name="phoneCode"
    type="text"
    tabindex="1" //tab键切换
    auto-complete="on"
    style="width: 65%"
  />
  <div class="code" @click="refreshCode" style="float: right">
    <s-identify :identifyCode="identifyCode"></s-identify>
  </div>
</el-form-item>
<el-button :loading="loading" type="success" style="width: 81%;  margin-bottom: 10px;  letter-spacing: 5px; float: right;border-radius: 0;" @click.native.prevent="handleLogin">登录</el-button>
import SIdentify from '../../components/page/identify'

components:{
  SIdentify
},
data() {
  const validateUsername = (rule, value, callback) => {
    if (value.trim().length > 0) {
      callback()
    } else {
      callback(new Error('请输入用户名'))
    }
  };
  const validatePassword = (rule, value, callback) => {
    if (value.length < 6) {
      callback(new Error('密码不能少于6位'))
    } else {
      callback()
    }
  };
  const validatephoneCode = (rule, value, callback) => {
    if (value !== this.identifyCode) {
      callback(new Error('请输入正确的验证码'));
      //当错误时刷新验证码
      this.identifyCode = '';
      this.makeCode(this.identifyCodes, 4);
    } else {
      callback()
    }
  };
  return {
    identifyCodes: "1234567890",
    identifyCode: "",
    loginForm: {
      username: '',
      password: '',
      phoneCode: '',
    },
    loginRules: {
      username: [{ trigger: 'blur', validator: validateUsername }],
      password: [{ trigger: 'blur', validator: validatePassword }],
      phoneCode: [{trigger: true, validator: validatephoneCode }],//点击登录时校验,而不是在光标离开后校验
    },
    loading: false,
    passwordType: 'password',
    redirect: undefined,
    pasChecked:false
  }
},
watch: {
  $route: {
    handler: function(route) {
      this.redirect = route.query && route.query.redirect
    },
    immediate: true
  }
},
mounted() {
  this.identifyCode = "";
  this.makeCode(this.identifyCodes, 4);
  tokenUtils.getCookie()
},
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)
        ];
    }
  },
  showPwd() {
    if (this.passwordType === 'password') {
      this.passwordType = ''
    } else {
      this.passwordType = 'password'
    }
    this.$nextTick(() => {
      this.$refs.password.focus()
    })
  },

  changeChecked() {
    this.pasChecked = !this.pasChecked;
    this.handleLogin();
  },
  handleLogin() {
    //保存的账号
    let name=this.loginForm.username;
    //保存的密码
    let pass=this.loginForm.password;
    //判断复选框是否被勾选 勾选则调用配置cookie方法
    if(this.pasChecked == true){
      //传入账号名,密码,和保存天数3个参数
      tokenUtils.setCookie(name,pass,7);
    }else{
      tokenUtils.clearCookie()
    }
    this.$refs.loginForm.validate(valid => {
      if (valid) {
        this.loading = true;
        this.$store.dispatch('login_store', this.loginForm).then(response => {
          var res=response.data;
          console.log(res);
          if (res.status === 200){
            console.log('用户名密码和验证码',this.loginForm);
            console.log('验证码图片中数字',this.identifyCode);
            this.loading = false;
            this.$router.push({ path: '/' })
          }else {
            Message({
              message: res.message,
              type: 'error',
              duration: 800
            })
          }
          this.loading = false
        }).catch(() => {
          this.loading = false
        })
      }
    });
  },

/components/page/identify文件

<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: 35
      },
      backgroundColorMin: { // 验证码图片背景色最小值
        type: Number,
        default: 200
      },
      backgroundColorMax: {  // 验证码图片背景色最大值
        type: Number,
        default: 220
      },
      dotColorMin: { // 背景干扰点最小值
        type: Number,
        default: 60
      },
      dotColorMax: { // 背景干扰点最大值
        type: Number,
        default: 120
      },
      contentWidth: { //容器宽度
        type: Number,
        default: 85
      },
      contentHeight: { //容器高度
        type: Number,
        default: 32
      }
    },
    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(50, 160) //随机生成字体颜色
        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(-30, 30)
        // 修改坐标原点和旋转角度
        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 < 4; i++) {
          ctx.strokeStyle = this.randomColor(100, 200)
          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 < 30; 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>

 

点击图片切换数字,并在输入错误后点击登录会刷新验证码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用以下代码生成vue随机验证码: ``` <template> <div> <canvas ref="canvas" @click="refreshCode"></canvas> </div> </template> <script> export default { data() { return { code: '', canvasWidth: 120, canvasHeight: 40 } }, mounted() { this.refreshCode(); }, methods: { refreshCode() { let canvas = this.$refs.canvas; let ctx = canvas.getContext('2d'); // 生成随机验证码 let chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; let length = 4; let code = ''; for (let i = 0; i < length; i++) { code += chars.charAt(Math.floor(Math.random() * chars.length)); } this.code = code; // 绘制验证码 ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight); ctx.font = 'bold 20px Arial'; ctx.fillText(code, 30, 25); // 绘制干扰线 for (let i = 0; i < 5; i++) { ctx.strokeStyle = this.randomColor(40, 180); ctx.beginPath(); ctx.moveTo(Math.random() * this.canvasWidth, Math.random() * this.canvasHeight); ctx.lineTo(Math.random() * this.canvasWidth, Math.random() * this.canvasHeight); ctx.stroke(); } // 绘制干扰点 for (let i = 0; i < 30; i++) { ctx.fillStyle = this.randomColor(0, 255); ctx.beginPath(); ctx.arc(Math.random() * this.canvasWidth, Math.random() * this.canvasHeight, 1, 0, 2 * Math.PI); ctx.fill(); } }, randomColor(min, max) { let r = Math.floor(Math.random() * (max - min) + min); let g = Math.floor(Math.random() * (max - min) + min); let b = Math.floor(Math.random() * (max - min) + min); return `rgb(${r},${g},${b})`; } } } </script> ``` 这段代码使用了canvas绘制验证码,包括验证码的生成、绘制、干扰线和干扰点的绘制。在模板中,使用canvas标签引用canvas元素,在mounted函数中调用refreshCode方法生成验证码。refreshCode方法会生成随机验证码并绘制到canvas上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值