• 【vue】canvas验证码组件--数字/数字加字母


    基于canvas的数字/数字+字符验证码   SIdentify.vue 组件
    <!-- 基于canvas的数字/数字+字符验证码 -->
    <!-- 调用格式
         <s-identify
         @func="getMsgFormSon"
         :isRefreshCode="isRefreshCode"
         :identifyCodes="identifyCodes"   //可选传,选传写法有要求
         ></s-identify> -->
    <template>
      <div class="s-canvas">
        <canvas id="s-canvas" :width="contentWidth" :height="contentHeight"></canvas>
      </div>
    </template>
    <script>
    export default {
      name: "SIdentify",
      props: {
        isRefreshCode: {
          type: Boolean,
          default: false
        },
        identifyCodes: {
          type: Array
        },
        identifyLen: {
          type: Number,
          default: 4
        },
        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: 32
        }
      },
      data() {
        return {
          nums: [
            "1",
            "2",
            "3",
            "4",
            "5",
            "6",
            "7",
            "8",
            "9",
            "0",
            "A",
            "B",
            "C",
            "D",
            "E",
            "F",
            "G",
            "H",
            "I",
            "J",
            "K",
            "L",
            "M",
            "N",
            "O",
            "P",
            "Q",
            "R",
            "S",
            "T",
            "U",
            "V",
            "W",
            "X",
            "Y",
            "Z",
            "a",
            "b",
            "c",
            "d",
            "e",
            "f",
            "g",
            "h",
            "i",
            "j",
            "k",
            "l",
            "m",
            "n",
            "o",
            "p",
            "q",
            "r",
            "s",
            "t",
            "u",
            "v",
            "w",
            "x",
            "y",
            "z"
          ],
          identifyText: ""
        };
      },
      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 + ")";
        },
        // 绘制干扰线
        drawLine(ctx) {
          for (let i = 0; i < 6; 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 < 50; i++) {
            ctx.fillStyle = this.randomColor(0, 255);
            ctx.beginPath();
            ctx.arc(
              this.randomNum(0, this.contentWidth),
              this.randomNum(0, this.contentHeight),
              1,
              0,
    * Math.PI
            );
            ctx.fill();
          }
        },
        // 生成l长度的验证码
        makeCode(o, l) {
          let identifyCodes = o;
          this.identifyText = "";
          for (let i = 0; i < l; i++) {
            this.identifyText +=
              identifyCodes[this.randomNum(0, identifyCodes.length)];
          }
        },
        // 验证码文本
        drawText(ctx, txt, i) {
          ctx.fillStyle = this.randomColor(this.colorMin, this.colorMax);
          ctx.font =
            this.randomNum(this.fontSizeMin, this.fontSizeMax) + "px SimHei";
          let x = (i + 1) * (this.contentWidth / (this.identifyText.length + 1));
          let 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);
        },
        // 验证码图形
        drawPic() {
          let identifyCodesArray = this.identifyCodes
            ? this.identifyCodes
            : this.nums;
          this.makeCode(identifyCodesArray, this.identifyLen);
          let identifyCode = "";
          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);
          console.log(this.identifyText, "huizhi");
          // 绘制文字
          for (let i = 0; i < this.identifyLen; i++) {
            this.drawText(ctx, this.identifyText[i], i);
            identifyCode += this.identifyText[i];
          }
          //   for (let i = 0; i < this.identifyArray.length; i++) {
          //     this.drawText(ctx, this.identifyArray[i], i);
          //   }
          this.drawLine(ctx);
          this.drawDot(ctx);
          console.log(identifyCode, "要传的值");
          // 向父组件传值
          this.$emit("func", identifyCode);
        }
      },
      watch: {
        if (this.isRefreshCode) {
            this.drawPic();
          }
      },
      mounted() {
        this.drawPic();
      }
    };
    </script>
    <style lang="scss" scoped>
    .s-canvas {
      height: 32px;
      canvas {
        margin-top: 1px;
        margin-left: 8px;
      }
    }
    </style>
    View Code

    父组件调用

    ①默认 数字+字母验证码 形式

    <template>
      <div>
         <el-input v-model="verificationCode" placeholder="验证码" />
          <div class="identify-code" @click="refreshCode">
                    <!--验证码组件-->
                    <s-identify @func="getSidentifyCode" :isRefreshCode="isRefreshCode"></s-identify>
          </div>
    
      </div>
    </template>
    <script>
    import Vue from "vue";
    import SIdentify from "./common/SIdentify";
    
    export default {
      components: { SIdentify },
      data() {
        return {
          verificationCode: "",
          identifyCode: "",
          isRefreshCode: false,
        };
      },
      created() {
        // this.refreshCode();
      },
      mounted() {},
      watch: {},
      methods: {
        refreshCode() {
          this.identifyCode = "";
          this.isRefreshCode = true;   //更改状态--SIdentify组件中监听该状态
        },
        getSidentifyCode(data) {
          this.identifyCode = data;
          this.isRefreshCode = false;
          console.log(this.identifyCode, "接收到的code");
        }
      }
    };
    </script>
    <style lang="scss" scoped>
      .identify-code {
        display: inline-block;
      }
    }
    </style>
    View Code

    ②通过传  纯数字  为数字验证码

    <template>
      <div>
         <el-input v-model="verificationCode" placeholder="验证码" />
          <div class="identify-code" @click="refreshCode">
                    <!--验证码组件-->
                    <s-identify @func="getSidentifyCode" :isRefreshCode="isRefreshCode"></s-identify>
          </div>
    
      </div>
    </template>
    <script>
    import Vue from "vue";
    import SIdentify from "./common/SIdentify";
    
    export default {
      components: { SIdentify },
      data() {
        return {
          verificationCode: "",
          identifyCodes: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"],
          identifyCode: "",
          isRefreshCode: false,
        };
      },
      created() {
        this.refreshCode();
      },
      mounted() {},
      watch: {},
      methods: {
        refreshCode() {
          this.identifyCode = "";
          this.isRefreshCode = true;   //更改状态--SIdentify组件中监听该状态
          // 随机排序
          if (this.identifyCodes.length) {
            let tempCodesArray = this.identifyCodes.sort(function() {
              return Math.random() - 0.5;
            });
            this.identifyCodes = tempCodesArray;
          }
        },
        getSidentifyCode(data) {
          this.identifyCode = data;
          this.isRefreshCode = false;
          console.log(this.identifyCode, "接收到的code");
        }
      }
    };
    </script>
    <style lang="scss" scoped>
      .identify-code {
        display: inline-block;
      }
    }
    </style>
    View Code

         当用方式②时, SIdentify.vue 组件 可以略去 isRefreshCode的监听判断,改为监听 identifyCodes

         代码段为 

    SIdentify.vue
    
    <script>
    export default { 
    ... 
      watch: {
         identifyCodes() {
           this.drawPic();
         }
       //,
       // isRefreshCode() {
       //   this.drawPic();
       // }
      }
    
    };
    </script>
    <style lang="scss" scoped>
    .
    .
    .
    </style>
    View Code
  • 相关阅读:
    android activity状态的保存
    java android 序列号serializable和parcelable
    java 中的 自定义viewUtils框架
    CSS隐藏元素的几种妙法
    WCF、WebAPI、WCFREST、WebService之间的区别
    前端大全
    最全前端资源汇集
    Unicode和汉字编码小知识
    关于写保护
    js实现密码加密
  • 原文地址:https://www.cnblogs.com/smilexumu/p/11947250.html
Copyright © 2020-2023  润新知