Vueの認証コード - 高度なカスタムコンポーネント

最近のプロジェクト認証コードを使用するには、オンライン検索の多くがありますが、基本的に4つの純粋なデジタルコードの同じパターンです。テンプレート生成プロジェクト、それがアップグレードされているので、需要を満たしていないことが原因提供Xiongtaiへのすべてのおかげでの初。

状況に使用するもの満たすために変換を介して、画像検証コード:①、確認コードデジット;②、純粋なデジタル、純粋な文字コード、③、数字と文字混合コード;④、文字の場合、⑤、デジタル混合ビットの各々の及び文字(ケース);⑥、混合しながらそれぞれのランダムに生成されたビット、⑦、コードがランダムに順序付けられました。それは、おおよそこれらの基本的なニーズの組み合わせに満たすことができる、見てあまり話をしませんでした -

図1に示すように、第一世代のメッシュキャンバスXiongtaiパラメータ動きについて

パラメータ 説明 タイプ デフォルト値
identifyCode 画像検証コードを表示します 1234
fontSizeMin フォントサイズ、および最小値 16
fontSizeMax フォントサイズ、最大 40
backgroundColorMin 背景色、最小カラー値、最小値 180
backgroundColorMax 背景色の最大カラー値255の最大値 240
colorMin フォント色、最小カラー値、最小値0 50
colorMax フォント色の最大カラー値255の最大値 160
lineColorMin カラーラインの干渉色値の最小値、最小値は0であります 40
lineColorMax 最大255マックスラインカラー干渉色、 180
dotColorMin 干渉色の点の色値の最小値、最小値は0であります 0
dotColorMax 最大255色に最大の干渉色、 255
contentWidth キャンバスの幅 160
contentHeight キャンバスの高さ 40

2、コンポーネントデビューidentify.vue主人公の子供

<template>
  <canvas id="s-canvas" :width="contentWidth" :height="contentHeight"></canvas>
</template>
<script>
export default {
  name: 'SIdentify',
  props: {
    // 图片验证码
    identifyCode: {
      type: String,
      default: '1234'
    },
    // 字体最小值
    fontSizeMin: {
      type: Number,
      default: 28
    },
    // 字体最大值
    fontSizeMax: {
      type: Number,
      default: 34
    },
    // 背景颜色色值最小值,最小为0
    backgroundColorMin: {
      type: Number,
      default: 200
    },
    // 背景颜色色值最大值,最大为255
    backgroundColorMax: {
      type: Number,
      default: 240
    },
    // 字体颜色色值最小值,最小为0
    colorMin: {
      type: Number,
      default: 0
    },
    // 字体颜色色值最大值,最大为255
    colorMax: {
      type: Number,
      default: 180
    },
    // 干扰线颜色色值最小值,最小为0
    lineColorMin: {
      type: Number,
      default: 150
    },
    // 干扰线颜色色值最大值,最大为255
    lineColorMax: {
      type: Number,
      default: 200
    },
    // 干扰点颜色色值最小值,最小为0
    dotColorMin: {
      type: Number,
      default: 100
    },
    // 干扰点颜色色值最大值,最大为255
    dotColorMax: {
      type: Number,
      default: 250
    },
    // 画布宽度
    contentWidth: {
      type: Number,
      default: 100
    },
    // 画布高度
    contentHeight: {
      type: Number,
      default: 40
    }
  },
  mounted () {
    this.drawPic()
  },
  methods: {
    /**
     * 生成一个随机数
     * @param {number} min 随机数最小值
     * @param {number} max 随机数最大值
     */
    randomNum (min, max) {
      return Math.floor(Math.random() * (max - min) + min)
    },

    /**
     * 生成一个随机的颜色
     * @param {number} min 随机数最小值
     * @param {number} max 随机数最大值
     */
    randomColor (min, max) {
      const r = this.randomNum(min, max)
      const g = this.randomNum(min, max)
      const b = this.randomNum(min, max)
      return 'rgb(' + r + ',' + g + ',' + b + ')'
    },

    /**
     * 绘制图片验证码
     */
    drawPic () {
      let canvas = document.querySelector('#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)
      // 绘制干扰点
      this.drawDot(ctx)
      // 绘制验证码
      for (let i = 0; i < this.identifyCode.length; i++) {
        this.drawText(ctx, this.identifyCode[i], i)
      }
      // 绘制干扰线
      this.drawLine(ctx)
    },

    /**
     * 绘制文本单个验证码
     * @param {object} ctx canvas上下文对象
     * @param {string} txt 单个验证码
     * @param {number} i 单个验证码序号
     */
    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)
      let 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)
    },

    /**
     * 绘制干扰线
     * @param {object} ctx canvas上下文对象
     */
    drawLine (ctx) {
      for (let i = 0; i < 8; 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()
      }
    },

    /**
     * 绘制干扰点
     * @param {object} ctx canvas上下文对象
     */
    drawDot (ctx) {
      for (let i = 0; i < 60; 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()
    }
  }
}
</script>

図3に示すように、画像検証コード参照の成分

プレゼンテーションを容易にするために、App.vueページに直接引用されました

<template>
  <div id="app" @click="refreshCode">
    <s-identify :identifyCode="identifyCode"></s-identify>
  </div>
</template>

<script>
import SIdentify from './components/identify'
export default {
  name: 'App',
  data () {
    return {
      makeCode: '',
      identifyCode: ''
    }
  },
  mounted () {
    this.makeIdentifyCode({ randomTypeLen: true })
  },
  methods: {
    /**
     * 随机生成一个0~9之间的数
     */
    randomNum () {
      return Math.floor(Math.random() * 10)
    },

    /**
     * 随机生成一个字母
     * @param {boolean} isUupper 生成大写字母
     */
    randomAlphabet ({ isUupper = false } = {}) {
      // a的Unicode值为97,z的Unicode值为123
      const alphabet = String.fromCharCode(Math.floor(Math.random() * 25) + 97)
      if (!isUupper) {
        return alphabet
      } else {
        return alphabet.toUpperCase()
      }
    },

    /**
     * 生成图片验证码
     * @param {number} length 图片验证码位数
     * @param {boolean} typeMix 数字和字母混合
     * @param {string} pureNumber 纯数字('number')或者字母('alphabet')
     * @param {boolean} randomTypeLen 随机生成类型个数组合
     * @param {boolean} capsLookMix 字母大小写混合
     * @param {number} numLength 混合类型下的数字个数
     * @param {number} uupperLength 大写字母的个数
     */
    makeIdentifyCode ({ length = 4, typeMix = true, pureNumber = 'alphabet', randomTypeLen = false, capsLookMix = false, numLength = 2, uupperLength = 1 } = {}) {
      this.makeCode = ''
      // 数字和字母混合
      if (typeMix) {
        // 随机生成类型个数组合
        if (randomTypeLen) {
          // 字母大小写混合
          if (capsLookMix) {
            const numLength = Math.floor(Math.random() * length) + 1
            const uupperLength = numLength === length ? 0 : Math.floor(Math.random() * (length - numLength)) + 1
            for (let i = 0; i < numLength; i++) {
              this.makeCode += this.randomNum()
            }
            for (let i = 0; i < uupperLength; i++) {
              this.makeCode += this.randomAlphabet({ isUupper: true })
            }
            if (numLength + uupperLength < length) {
              for (let i = 0; i < length - numLength - uupperLength; i++) {
                this.makeCode += this.randomAlphabet()
              }
            }
          } else {
            const numLength = Math.floor(Math.random() * length) + 1
            for (let i = 0; i < numLength; i++) {
              this.makeCode += this.randomNum()
            }
            if (numLength < length) {
              for (let i = 0; i < length - numLength; i++) {
                this.makeCode += this.randomAlphabet()
              }
            }
          }
        } else {
          // 字母大小写混合
          if (capsLookMix) {
            const tempNumLength = numLength < 0 ? 2 : numLength > length ? 2 : numLength
            const tempUupperLength = uupperLength < 0 ? 1 : uupperLength > length - tempNumLength ? 1 : uupperLength
            for (let i = 0; i < tempNumLength; i++) {
              this.makeCode += this.randomNum()
            }
            for (let i = 0; i < tempUupperLength; i++) {
              this.makeCode += this.randomAlphabet({ isUupper: true })
            }
            if (tempNumLength + tempUupperLength < length) {
              for (let i = 0; i < length - tempNumLength - tempUupperLength; i++) {
                this.makeCode += this.randomAlphabet()
              }
            }
          } else {
            const tempNumLength = numLength < 0 ? 2 : numLength > length ? 2 : numLength
            for (let i = 0; i < tempNumLength; i++) {
              this.makeCode += this.randomNum()
            }
            if (tempNumLength < length) {
              for (let i = 0; i < length - tempNumLength; i++) {
                this.makeCode += this.randomAlphabet()
              }
            }
          }
        }
      } else {
        // 纯数字('number')
        if (pureNumber === 'number') {
          for (let i = 0; i < length; i++) {
            this.makeCode += this.randomNum()
          }
        }
        // 纯字母('alphabet')
        if (pureNumber === 'alphabet') {
          // 字母大小写混合
          if (capsLookMix) {
            const tempUupperLength = uupperLength < 0 ? 1 : uupperLength > length ? 1 : uupperLength
            for (let i = 0; i < tempUupperLength; i++) {
              this.makeCode += this.randomAlphabet({ isUupper: true })
            }
            if (tempUupperLength < length) {
              for (let i = 0; i < length - tempUupperLength; i++) {
                this.makeCode += this.randomAlphabet()
              }
            }
          } else {
            for (let i = 0; i < length; i++) {
              this.makeCode += this.randomAlphabet()
            }
          }
        }
      }
      this.shuffle(this.makeCode)
    },

    /**
     * 图片验证码随机排序
     * @param {string} str 图片验证码
     */
    shuffle (str) {
      this.identifyCode = [...str].sort(() => Math.random() - 0.5).join('')
      console.log(this.identifyCode)
    },

    /**
     * 更换图片验证码
     */
    refreshCode () {
      this.makeIdentifyCode({ randomTypeLen: true })
    }
  },
  components: {
    's-identify': SIdentify
  }
}
</script>

だから〜、完成ものになります

おすすめ

転載: www.cnblogs.com/darkerxi/p/12036542.html