【验证码功能合集】vue简单实现验证码功能,纯前端实现验证码,拿来即用【输入,滑动,拼图】

效果图

可以让输入的验证码和图片验证码比对。
在这里插入图片描述
在这里插入图片描述
上面的是验证码的组件,直接复制贴里面就行了,然后引入到你需要的地方
在这里插入图片描述
很简单的两个步骤搞定

(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: 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: 90,
    },
    contentHeight: {
      // 容器高度
      type: Number,
      default: 38,
    },
  },
  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");
      //创建一个2D对象作为上下文。
      let ctx = canvas.getContext("2d");
      ctx.textBaseline = "bottom";
      // 绘制背景
      ctx.fillStyle = "#e6ecfd";
      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>

(2)使用组件

在这里就是直接引入组件,然后把组件放到对应的位置就行了。参数看需要传

<template>
  <div class="home">
    <el-row>
      <el-col :span="4"
        ><el-input
          placeholder="请输入验证码"
          v-model="formLogin.code"
        ></el-input
      ></el-col>
      <el-col :span="4">
        <div class="login-code" width="100%" @click="refreshCode">
          <!--验证码组件-->
          <dentify :identifyCode="identifyCode"></dentify></div
      ></el-col>
    </el-row>
    <div><el-button @click="submit">提交</el-button></div>
  </div>
</template>

<script>
import dentify from "./dentify";
export default {
  name: "HomeView",
  components: {
    dentify,
  },
  data() {
    return {
      // 表单提交内容
      formLogin: {
        code: "", //验证码输入框
      },
      identifyCodes: "1234567890abcdefjhijklinopqrsduvwxyz", //随机串内容,从这里随机抽几个显示验证码
      identifyCode: "", //验证码图片内容
    };
  },
  mounted() {
    // 初始化验证码
    this.identifyCode = "";
    //参数:(1)随机串内容。(2)验证码显示位数
    this.makeCode(this.identifyCodes, 4);
  },
  methods: {
    // 重置验证码
    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)];
      }
    },
    //随机数字:用于当角标拿字符串的值
    randomNum(min, max) {
      return Math.floor(Math.random() * (max - min) + min);
    },
    submit() {
      console.log("验证码:", this.identifyCode);
      console.log("用户输入的验证码:",this.formLogin.code);
      console.log('是否验证通过:',this.identifyCode==this.formLogin.code);
    },
  },
};
</script>

滑动验证码

效果图
在这里插入图片描述
在这里插入图片描述
这个不需要下载插件,直接复制就可以用。

代码

这个直接复制了就可以用,然后可以当成组件用在需要的地方。

<template>
<!-- 滑动验证码 -->
  <div ref="dragDiv" class="drag">
    <div class="drag_bg"></div>
    <div class="drag_text">{{ confirmWords }}</div>
    <div ref="moveDiv" :class="{'handler_ok_bg':confirmSuccess}" class="handler handler_bg"
         style="position: absolute;top: 0px;left: 0px;" @mousedown="mousedownFn($event)"></div>
  </div>
</template>

<script>
  export default {
    data () {
      return {
        beginClientX: 0, /* 距离屏幕左端距离 */
        mouseMoveStata: false, /* 触发拖动状态  判断 */
        maxwidth: '', /* 拖动最大宽度,依据滑块宽度算出来的 */
        confirmWords: '拖动滑块验证', /* 滑块文字 */
        confirmSuccess: false /* 验证成功判断 */
      }
    },
    mounted () {
      this.maxwidth = this.$refs.dragDiv.clientWidth - this.$refs.moveDiv.clientWidth;
      document.getElementsByTagName('html')[0].addEventListener('mousemove', this.mouseMoveFn);
      document.getElementsByTagName('html')[0].addEventListener('mouseup', this.moseUpFn)
    },
    methods: {
      mousedownFn: function (e) {
        if (!this.confirmSuccess) {
          e.preventDefault && e.preventDefault(); // 阻止文字选中等 浏览器默认事件
          this.mouseMoveStata = true;
          this.beginClientX = e.clientX;
        }
      },
      // mousedoen 事件
      successFunction () {
        this.confirmSuccess = true
        this.confirmWords = '验证通过';
        if (window.addEventListener) {
          document.getElementsByTagName('html')[0].removeEventListener('mousemove', this.mouseMoveFn);
          document.getElementsByTagName('html')[0].removeEventListener('mouseup', this.moseUpFn);
        } else {
          document.getElementsByTagName('html')[0].removeEventListener('mouseup', () => {});
        }
        document.getElementsByClassName('drag_text')[0].style.color = '#fff'
        document.getElementsByClassName('handler')[0].style.left = this.maxwidth + 'px';
        document.getElementsByClassName('drag_bg')[0].style.width = this.maxwidth + 'px';
      },
      // 验证成功函数
      mouseMoveFn (e) {
        if (this.mouseMoveStata) {
          let width = e.clientX - this.beginClientX;
          if (width > 0 && width <= this.maxwidth) {
            document.getElementsByClassName('handler')[0].style.left = width + 'px';
            document.getElementsByClassName('drag_bg')[0].style.width = width + 'px';
          } else if (width > this.maxwidth) {
            this.successFunction();
            console.log('验证成功');
          }
        }
      },
      // mousemove事件
      moseUpFn (e) {
        this.mouseMoveStata = false;
        var width = e.clientX - this.beginClientX;
        if (width < this.maxwidth) {
          document.getElementsByClassName('handler')[0].style.left = 0 + 'px';
          document.getElementsByClassName('drag_bg')[0].style.width = 0 + 'px';
        }
      }
    }
  }
</script>

<style scoped>
    .drag{
        position: relative;
        background-color: #e8e8e8;
        width: 100%;
        height: 34px;
        line-height: 34px;
        text-align: center;
    }
    .handler{
        width: 40px;
        height: 32px;
        border: 1px solid #ccc;
        cursor: move;
    }
    .handler_bg{
        background: #fff url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTEyNTVEMURGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTEyNTVEMUNGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2MTc5NzNmZS02OTQxLTQyOTYtYTIwNi02NDI2YTNkOWU5YmUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+YiRG4AAAALFJREFUeNpi/P//PwMlgImBQkA9A+bOnfsIiBOxKcInh+yCaCDuByoswaIOpxwjciACFegBqZ1AvBSIS5OTk/8TkmNEjwWgQiUgtQuIjwAxUF3yX3xyGIEIFLwHpKyAWB+I1xGSwxULIGf9A7mQkBwTlhBXAFLHgPgqEAcTkmNCU6AL9d8WII4HOvk3ITkWJAXWUMlOoGQHmsE45ViQ2KuBuASoYC4Wf+OUYxz6mQkgwAAN9mIrUReCXgAAAABJRU5ErkJggg==") no-repeat center;
    }
    .handler_ok_bg{
        background: #fff url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDlBRDI3NjVGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDlBRDI3NjRGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDphNWEzMWNhMC1hYmViLTQxNWEtYTEwZS04Y2U5NzRlN2Q4YTEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+k+sHwwAAASZJREFUeNpi/P//PwMyKD8uZw+kUoDYEYgloMIvgHg/EM/ptHx0EFk9I8wAoEZ+IDUPiIMY8IN1QJwENOgj3ACo5gNAbMBAHLgAxA4gQ5igAnNJ0MwAVTsX7IKyY7L2UNuJAf+AmAmJ78AEDTBiwGYg5gbifCSxFCZoaBMCy4A4GOjnH0D6DpK4IxNSVIHAfSDOAeLraJrjgJp/AwPbHMhejiQnwYRmUzNQ4VQgDQqXK0ia/0I17wJiPmQNTNBEAgMlQIWiQA2vgWw7QppBekGxsAjIiEUSBNnsBDWEAY9mEFgMMgBk00E0iZtA7AHEctDQ58MRuA6wlLgGFMoMpIG1QFeGwAIxGZo8GUhIysmwQGSAZgwHaEZhICIzOaBkJkqyM0CAAQDGx279Jf50AAAAAABJRU5ErkJggg==") no-repeat center;
    }
    .drag_bg{
        background-color: #7ac23c;
        height: 34px;
        width: 0px;
    }
    .drag_text{
        position: absolute;
        top: 0px;
        width: 100%;text-align: center;
        -moz-user-select: none;
        -webkit-user-select: none;
        user-select: none;
        -o-user-select:none;
        -ms-user-select:none;
    }
</style>


滑动拼图验证码

效果图

图片是我自己定义的,你们刚复制上去可能不一样
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这个有一个插件可以直接使用,很简单
先下载一下

npm install vue-puzzle-vcode --save

代码

上面的下载好了后,这个直接复制就可以使用~
注意,复制使用后,页面上只有一个按钮,点击验证按钮才会弹框出来这个验证码,别以为没使用成功,我刚开始就是使用后页面上没有验证码只有一个按钮,我还以为我没引入成功呢 - -!

<template>
    <div>
        <Vcode :show="isShow" @success="success" @close="close" @fail='fail'></Vcode>
        <button @click="submit">登录</button>
    </div>
</template>

<script>
    import Vcode from "vue-puzzle-vcode";
    export default {
        components: {
            Vcode
        },
        data() {
            return {
                isShow: false, // 验证码模态框是否出现
            }
        },
        methods: {
            submit(){
                this.isShow = true;
            },
            // 用户通过了验证
            success(msg){
                this.isShow = false; // 通过验证后,需要手动隐藏模态框
                console.log('验证通过');
            },
            // 用户点击遮罩层,应该关闭模态框
            close(){
                this.isShow = false;
            },
            // 用户验证失败
            fail(){
                console.log('验证失败');
            }
        }
    }
</script>

<style scoped>

</style>

自定义图片方法

只需要在这个组件上加参数 :imgs 就可以了。
注意:这里后面的数组内可以放多个图片,多个图片他就是刷新的时候会更换,如果只放一个图片就换来换去都是这一个图片
当然你可以不设置这个,这个插件有默认自带的几张图片,不介意的可以直接使用。
还有注意这个图片不要跨域,不然用不了。
在这里插入图片描述
还有不明白的可以去插件官方看 地址这里

旋转图片验证功能

效果图

在这里插入图片描述
在这里插入图片描述

先下载一个插件

npm i vue-drag-verify-img-rotate -S

代码

复制即用


<template>
  <div>
    <drag-verify-rotate
      ref="sss"
      :imgsrc="imgsrc"
      :isPassing.sync="isPassing"
      text="请按住滑块拖动"
      successText="验证通过"
      handlerIcon="el-icon-d-arrow-right"
      successIcon="el-icon-circle-check"
      @refresh="reimg"
      @passcallback="pass"
      @passfail="passfail"
    >
    </drag-verify-rotate>
  </div>
</template>

<script>
import dragVerifyRotate from "vue-drag-verify-img-rotate";
export default {
  data() {
    return {
      //验证状态,是否通过
      isPassing: false,
      value: "",
      // 图片1:1
      imgsrc:
        "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F202005%2F02%2F20200502005417_fh4P4.thumb.1000_0.jpeg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1665907837&t=4cc1cea78e3271d2ef86d8ad6d4481c3",
    };
  },
  components: {
    dragVerifyRotate,
  },
  methods: {
    //刷新
    reimg() {
      console(1);
    },
    //通过验证
    pass() {
      this.$message({
        message: "验证通过了",
        type: "success",
      });
    },
    //验证失败
    passfail() {
      this.$message.error("验证失败了");
    },
    //   reset() {
    //     this.isPassing = false;
    //     this.$refs.dragVerify.reset()
    //   },
  },
};
</script>
<style>
.verifybox {
  display: flex;
}
</style>

Vue手机验证码登录组件需要包含以下功能: 1. 输入手机号码和验证码 2. 点击发送验证码按钮,发送验证码到手机 3. 倒计时功能,倒计时结束后可以重新发送验证码 4. 验证码输入框自动聚焦 5. 手机号码和验证码的实时校验 6. 登录按钮,点击后根据手机号码和验证码进行登录 下面是一个简单的示例代码: ```vue <template> <div> <input type="text" v-model="phone" placeholder="请输入手机号码" @input="validatePhone"> <div> <input type="text" v-model="code" placeholder="请输入验证码" @input="validateCode" ref="codeInput"> <button :disabled="countdown > 0" @click="sendCode">{{ buttonText }}</button> </div> <button :disabled="!isValid" @click="login">登录</button> </div> </template> <script> export default { data() { return { phone: '', code: '', countdown: 0, isValid: false } }, computed: { buttonText() { return this.countdown > 0 ? `${this.countdown}s` : '发送验证码' } }, methods: { validatePhone() { // TODO: 手机号码校验 this.isValid = this.phone.length === 11 && /^\d+$/.test(this.phone) }, validateCode() { // TODO: 验证码校验 this.isValid = this.code.length === 6 && /^\d+$/.test(this.code) }, sendCode() { // TODO: 发送验证码到手机 this.countdown = 60 const timer = setInterval(() => { this.countdown -= 1 if (this.countdown === 0) { clearInterval(timer) } }, 1000) this.$refs.codeInput.focus() }, login() { // TODO: 手机号码和验证码登录 } } } </script> ``` 在上面的示例代码中,我们定义了一个包含手机号码和验证码输入框、发送验证码按钮和登录按钮的组件。其中,手机号码和验证码输入框通过 v-model 指令绑定 data 中的 phone 和 code 数据,发送验证码按钮通过 @click 监听点击事件,调用 sendCode 方法发送验证码,并且通过计时器实现倒计时功能,在发送验证码的时候将验证码输入框的焦点聚焦到输入框中,登录按钮通过 :disabled 控制是否可以点击,如果手机号码和验证码都符合要求,则 isValid 为 true,登录按钮才能点击。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

接口写好了吗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值