vue生成圖片驗證碼

最近作項目接觸Vue,前端生成驗證碼。原理其實很簡單,首先是生成隨機數,而後用canvas繪製。
網上有一些現成的資料,不必重複造輪子,我是在他們基礎上完善了父組件,簡化了子組件的調用:
   identify.vue(子組件):是一個獨立的組件,負責生成驗證碼和繪製圖片;
   codetest.vue(父組件):引入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: {
      fresh:true,
      fontSizeMin: {
        type: Number,
        default: 20
      },
      fontSizeMax: {
        type: Number,
        default: 36
      },
      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
      }
    },
    data() {
      return {
        identifyCodes: "1234567890",
        identifyCode: ""
      };
    },
    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(this.colorMin, this.colorMax)
    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(-10, 10)
    // 修改座標原點和旋轉角度
    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 < 3; 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 < 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()
    }
  },
  // 生成四位隨機驗證碼
  makeCode(o, l) {
        this.identifyCode="";
        for (let i = 0; i < l; i++) {
          this.identifyCode += this.identifyCodes[
            this.randomNum(0, this.identifyCodes.length)
            ];
        }
 
        //繪製圖片
        this.drawPic()
 
        //傳值給父組件
        this.$emit('makedCode',this.identifyCode);
 
 
  }
  },
  watch: {
    fresh () {   //監聽事件
      this.makeCode(this.identifyCodes, 4);
    }
  },
  }
</script>

 

 
codetest.vue(在頁面進行使用):
 
<template>
  <div class="code" @click="refreshCode">
 <!--   :fresh:父組件向子組件傳送刷新驗證碼的信號;
    @makedCode:子組件向父組件傳送驗證碼的值-->
    <s-identify :fresh="flag" @makedCode="getMakedCode"></s-identify>
  </div>
</template>

<script>
  import SIdentify from '@/components/identify.vue'
  export default {
    name: "codetest",
    data() {
      return {
        flag:true,  //該值變化,就會觸發刷新
        code:'',  //刷新後的驗證碼
      };
    },
  components : {
    SIdentify,
  },
  // 驗證碼初始化
  mounted() {
    this.flag = !this.flag;
  },
  methods: {
    // 切換驗證碼
    refreshCode() {
      this.flag = !this.flag;
    },
    getMakedCode(code){
      this.code = code
      console.log("getMakedCode:",this.code);
    }
  }
  };
</script>

<style>
  .code {
    /*margin: 400px auto;*/
    width: 114px;
    height: 40px;
    /*border: 1px solid red;*/
  }
</style>
 
測試效果:
 
相關文章
相關標籤/搜索