vue实现前端随机验证码(两种方法)

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

 

 

 1 // 第一种方法,span,不绘制干扰点
 2 <template>
 3   <div class="ValidCode disabled-select" :style="`width:${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     width: {
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

posted @ 2020-04-28 10:50  辰熙ali  阅读(8512)  评论(0编辑  收藏  举报