开发者社区> 佀无极> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

vue 图形验证码组件

简介: vue 图形验证码组件
+关注继续查看

1.新建公共组件 /src/page/common/IdentifyCode.vue

<template>
  <div class="canvas-box" @click="changeCode">
    <canvas id="cont-canvas" :width="contentWidth" :height="contentHeight"></canvas>
  </div>
</template>

<script>
export default {
  name: "IdentifyCode",
  data() {
    return {
      identifyCode: ""
    };
  },
  props: {
    identifyCodes: {
      //验证码从该字段中抽取生成
      type: String,
      default: "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678"
    },
    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: 100
    },
    contentHeight: {
      //容器高度
      type: Number,
      default: 40
    }
  },
  watch: {
    identifyCode() {
      this.drawPic();
    }
  },
  mounted() {
    this.drawPic();
    this.makeCode(this.identifyCodes, 4);
  },
  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("cont-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();
      }
    },
    /*切换验证码start*/
    changeCode() {
      this.identifyCode = "";
      this.makeCode(this.identifyCodes, 4);
    },
    makeCode(e, n) {
      for (let i = 0; i < n; i++) {
        this.identifyCode += e[this.randomNum(0, e.length)];
      }
      console.log('code = ',this.identifyCode)
      this.$emit("update:changeCode", this.identifyCode);
    },
    randomNum(min, max) {
      return Math.floor(Math.random() * (max - min) + min);
    }
    /*切换验证码end*/
  }
};
</script>
<style scoped>
.canvas-box {
    padding-top: 7px;
}
</style>

2.使用方法

<template>
    <div>
        <identify-code :changeCode.sync='identifyCode'></identify-code>
    </div>
</template>

<script>
import IdentifyCode from '@/page/common/IdentifyCode'
export default {
    components: {
        IdentifyCode
    },
    data() {
        return {
            identifyCode:'',    //当前生成的验证码
        }
    }
}
</script>

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Vue中如何自定义组件实现组件化开发(案例步骤及组件传值)
在前端项目中,对于大面积可以复用的地方我们通常对其进行组件化的封装,从而提高代码复用率,简化开发,也便于后期对代码进行维护和修改。
30 0
vue-组件传值
组件传值 不管 vue 还是react 亦或某个框架都是重点 记得有篇文章写了 ,其实有些情况 完全可以用 js自带 dataset来传值哦
79 0
知道vue组件同级传值吗?
知道vue组件同级传值吗?
37 0
vue组件传值的概括图
vue组件传值的概括图
70 0
vue 组件间传值
1、父组件给子组件传值 父组件: &lt;template&gt; &lt;child :name="name"&gt;&lt;/child&gt; &lt;/template&gt; &lt;script&gt; import child from ".
754 0
初识 Vue(05)---(组件间传值)
组件间传值(改进 TodoList) 改进 TodoList ,点击那个输出 ,那个输出就会消失 步骤一 TodoList 提交 ...
981 0
vue相关面试题2:1.封装vue组件作用;2双向数据绑定原理;3.Router 是什么;4.导航钩子有哪些
它们有以下参数。 ●to::即将要进入的目标路由对象。 ●from:当前导航正要离开的路由。 ●next: 一定要用这个函数才能到达下一个路由,如果不用就会遭到拦截。
64 0
vue面试题4:1.组件通信;2.路由嵌套;3.< keep-alive >作用
请说明< keep-alive >组件的作用 当< keep-alive >包 裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。 < keep-alive >是一个抽象组件,它自身不会渲染一个DOM元素,也不会出现在父组件链中。 当在< keep-alive >内切换组件时,它的activated 和deactivated 这两个生命周期钩子函数将会执行。
27 0
前端-vue基础56-组件注册命名方式
前端-vue基础56-组件注册命名方式
22 0
前端-vue基础54-组件注册注意事项
前端-vue基础54-组件注册注意事项
30 0
+关注
佀无极
脚踏实地,心存高远!
文章
问答
文章排行榜
最热
最新
相关电子书
更多
利用编译将 Vue 组件转成 React 组件
立即下载
基于VUE的单页面性能优化实践
立即下载
yqdh_58c128c6555...1510401796.pdf
立即下载