zoukankan      html  css  js  c++  java
  • vue实现前端随机验证码(两种方法)

    最近在做一个功能,前端实现随机验证码的生成,前端实现仅是单纯的一个小验证,若是想要实在的人机验证,还是需要由后端实现验证码的生成的。

     1 // 第一种方法,span,不绘制干扰点
     2 <template>
     3   <div class="ValidCode disabled-select" :style="`${width}; height:${height}`" @click="refreshCode">
     4     <span v-for="(item, index) in codeList" :key="index" :style="getStyle(item)">{{item.code}}</span>
     5   </div>
     6 </template>
     7 
     8 <script>
     9 export default {
    10   props: {
    11      {
    12       type: String,
    13       default: '100px'
    14     },
    15     height: {
    16       type: String,
    17       default: '34px'
    18     },
    19     length: {
    20       type: Number,
    21       default: 4
    22     }
    23   },
    24   data () {
    25     return {
    26       codeList: []
    27     }
    28   },
    29   mounted () {
    30     this.createdCode()
    31   },
    32   methods: {
    33     refreshCode () {
    34       this.createdCode()
    35     },
    36     createdCode () {
    37       const len = this.length
    38       const codeList = []
    39       const chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz0123456789'
    40       const charsLen = chars.length
    41       // 生成
    42       for (let i = 0; i < len; i++) {
    43         const rgb = [Math.round(Math.random() * 220), Math.round(Math.random() * 240), Math.round(Math.random() * 200)]
    44         codeList.push({
    45           code: chars.charAt(Math.floor(Math.random() * charsLen)),
    46           color: `rgb(${rgb})`,
    47           fontSize: `1${[Math.floor(Math.random() * 10)]}px`,
    48           padding: `${[Math.floor(Math.random() * 10)]}px`,
    49           transform: `rotate(${Math.floor(Math.random() * 90) - Math.floor(Math.random() * 90)}deg)`
    50         })
    51       }
    52       // 指向
    53       this.codeList = codeList
    54       // 将当前数据派发出去
    55       this.$emit('update:value', codeList.map(item => item.code).join(''))
    56     },
    57     getStyle (data) {
    58       return `color: ${data.color}; font-size: ${data.fontSize}; padding: ${data.padding}; transform: ${data.transform}`
    59     }
    60   }
    61 }
    62 </script>
    63 
    64 <style scoped lang="scss">
    65   .ValidCode{
    66     display: flex;
    67     justify-content: center;
    68     align-items: center;
    69     cursor: pointer;
    70     span{
    71       display: inline-block;
    72     }
    73   }
    74 </style>

      1 // 第二种方法 canvas 绘制干扰点干扰线
      2 <template>
      3   <div class="s-canvas" @click="createdCode">
      4     <canvas id="s-canvas" :width="contentWidth" :height="contentHeight"></canvas>
      5   </div>
      6 </template>
      7 <script>
      8 import Vue from 'vue'
      9 export default Vue.extend({
     10   props: {
     11     fontSizeMin: {
     12       type: Number,
     13       default: 25
     14     },
     15     fontSizeMax: {
     16       type: Number,
     17       default: 30
     18     },
     19     backgroundColorMin: {
     20       type: Number,
     21       default: 255
     22     },
     23     backgroundColorMax: {
     24       type: Number,
     25       default: 255
     26     },
     27     colorMin: {
     28       type: Number,
     29       default: 0
     30     },
     31     colorMax: {
     32       type: Number,
     33       default: 160
     34     },
     35     lineColorMin: {
     36       type: Number,
     37       default: 100
     38     },
     39     lineColorMax: {
     40       type: Number,
     41       default: 255
     42     },
     43     dotColorMin: {
     44       type: Number,
     45       default: 0
     46     },
     47     dotColorMax: {
     48       type: Number,
     49       default: 255
     50     },
     51     contentWidth: {
     52       type: Number,
     53       default: 120
     54     },
     55     contentHeight: {
     56       type: Number,
     57       default: 34
     58     }
     59   },
     60   data () {
     61     return {
     62       identifyCode: ''
     63     }
     64   },
     65   mounted () {
     66     this.createdCode()
     67   },
     68   methods: {
     69     // 生成4个随机数
     70     createdCode () {
     71       const len = 4
     72       const codeList = []
     73       const chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz0123456789'
     74       const charsLen = chars.length
     75       for (let i = 0; i < len; i++) {
     76         codeList.push(chars.charAt(Math.floor(Math.random() * charsLen)))
     77       }
     78       this.identifyCode = codeList.join('')
     79       this.$emit('getIdentifyCode', this.identifyCode.toLowerCase())
     80       this.drawPic()
     81     },
     82 
     83     // 生成一个随机数
     84     randomNum (min, max) {
     85       return Math.floor(Math.random() * (max - min) + min)
     86     },
     87     // 生成一个随机的颜色
     88     randomColor (min, max) {
     89       const r = this.randomNum(min, max)
     90       const g = this.randomNum(min, max)
     91       const b = this.randomNum(min, max)
     92       return 'rgb(' + r + ',' + g + ',' + b + ')'
     93     },
     94 
     95     drawPic () {
     96       const canvas = document.getElementById('s-canvas')
     97       const ctx = canvas.getContext('2d')
     98       ctx.textBaseline = 'bottom'
     99       // 绘制背景
    100       ctx.fillStyle = this.randomColor(this.backgroundColorMin, this.backgroundColorMax)
    101       ctx.fillRect(0, 0, this.contentWidth, this.contentHeight)
    102       // 绘制文字
    103       for (let i = 0; i < this.identifyCode.length; i++) {
    104         this.drawText(ctx, this.identifyCode[i], i)
    105       }
    106       this.drawLine(ctx)
    107       this.drawDot(ctx)
    108     },
    109 
    110     drawText (ctx, txt, i) {
    111       ctx.fillStyle = this.randomColor(this.colorMin, this.colorMax)
    112       ctx.font = this.randomNum(this.fontSizeMin, this.fontSizeMax) + 'px SimHei'
    113       const x = (i + 1) * (this.contentWidth / (this.identifyCode.length + 1))
    114       const y = this.randomNum(this.fontSizeMax, this.contentHeight - 5)
    115       var deg = this.randomNum(-45, 45)
    116       // 修改坐标原点和旋转角度
    117       ctx.translate(x, y)
    118       ctx.rotate(deg * Math.PI / 180)
    119       ctx.fillText(txt, 0, 0)
    120       // 恢复坐标原点和旋转角度
    121       ctx.rotate(-deg * Math.PI / 180)
    122       ctx.translate(-x, -y)
    123     },
    124 
    125     // 绘制干扰线
    126     drawLine (ctx) {
    127       for (let i = 0; i < 5; i++) {
    128         ctx.strokeStyle = this.randomColor(this.lineColorMin, this.lineColorMax)
    129         ctx.beginPath()
    130         ctx.moveTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight))
    131         ctx.lineTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight))
    132         ctx.stroke()
    133       }
    134     },
    135 
    136     // 绘制干扰点
    137     drawDot (ctx) {
    138       for (let i = 0; i < 80; i++) {
    139         ctx.fillStyle = this.randomColor(0, 255)
    140         ctx.beginPath()
    141         ctx.arc(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight), 1, 0, 2 * Math.PI)
    142         ctx.fill()
    143       }
    144     }
    145   }
    146 })
    147 </script>
    148 <style scoped>
    149 .s-canvas {
    150   height: 38px;
    151   cursor: pointer;
    152 }
    153 .s-canvas canvas{
    154   margin-top: 1px;
    155   margin-left: 8px;
    156 }
    157 </style>

    参考:https://www.cnblogs.com/web-aqin/p/10796326.html

  • 相关阅读:
    【VS开发】设置文档标题
    【VS开发】修改MainFrame窗口名称1
    【VS开发】修改MainFrame窗口名称1
    【DSP开发】ccsv6添加simulator功能
    【DSP开发】ccsv6添加simulator功能
    【VS开发】Cameralink接口
    【VS开发】Cameralink接口
    【VS开发】【图像处理】GigE和USB3 vision选择?
    【VS开发】【图像处理】GigE和USB3 vision选择?
    【VS开发】【图像处理】Pleora推出iPORT CL-U3外置抓帧器
  • 原文地址:https://www.cnblogs.com/Alioo/p/12792569.html
Copyright © 2011-2022 走看看