最近项目中要用到图片验证码,网上一查有很多,基本都是千篇一律的4位纯数字验证码。首先得感谢那位一代目兄台提供的模板,由于不能满足需求,所以对其进行了改造升级。

经改造的图片验证码能满足一下情形使用:①、验证码位数;②、纯数字和纯字母的验证码;③、数字和字母混合的验证码;④、字母的大小写;⑤、数字和字母(大小写)混合下各自的位数;⑥、随机生成混合情况下各自的位数;⑦、验证码随机排序。大致就这些组合吧,基本的需求都能满足,话不多说,看~

1、先把一代目兄台的canvas参数搬一下

参数 说明 类型 默认值
identifyCode 展示的图片验证码 string 1234
fontSizeMin 字体大小,最小值 number 16
fontSizeMax 字体大小,最大值 number 40
backgroundColorMin 背景颜色色值最小值,最小为 number 180
backgroundColorMax 背景颜色色值最大值,最大为255 number 240
colorMin 字体颜色色值最小值,最小为0 number 50
colorMax 字体颜色色值最大值,最大为255 number 160
lineColorMin 干扰线颜色色值最小值,最小为0 number 40
lineColorMax 干扰线颜色色值最大值,最大为255 number 180
dotColorMin 干扰点颜色色值最小值,最小为0 number 0
dotColorMax 干扰点颜色色值最大值,最大为255 number 255
contentWidth 画布宽度 number 160
contentHeight 画布高度 number 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>

就这样吧,完事儿~

Vue图片验证码-自定义组件高级版的更多相关文章

  1. vue.js2.0 自定义组件初体验

    理解 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能.在有些情况 ...

  2. vue图片上传组件

    前言:很多项目中都需要用到图片上传功能,而其多处使用的要求,为了避免重复造轮子,让我决定花费一些时间去深入了解,最终封装了一个vue的图片上传组件.现将总结再次,希望有帮助. Layout <d ...

  3. VUE 图片验证码

    1. 概述 1.1 说明 在开发过程中,有时候需要使用图片验证码进行增加安全强度,在点击图片时更新新的图片验证码,记录此功能,以便后期使用. 2. 示例 2.1 vue示例代码 <templat ...

  4. Vue.extend提供自定义组件的构造器

    Vue.extend 返回的是一个“扩展实例构造器”,也就是预设了部分选项的Vue实例构造器.经常服务于Vue.component用来生成组件,可以简单理解为当在模板中遇到该组件名称作为标签的自定义元 ...

  5. vue框架之自定义组件中使用v-model

    通常 vue在html常见表单空间支持v-model双向绑定例如 <input v-model="message" placeholder="edit me&quo ...

  6. vue怎么给自定义组件绑定原生事件

     下面主要以4个示例Demo演示(示例代码JS引用的Vue CDN),建议小伙伴直接复制示例代码运行查看, 赶时间的小伙伴可直接往下拉,看示例demo4 注:全局或局部注册的组件称为子组件,其中声明的 ...

  7. vue之全局自定义组件

    在项目开发中,往往需要使用到一些公共组件,比如,弹出消息.面包屑或者其它的组件,为了使用方便,将其以插件的形式融入到vue中,以面包屑插件为例: 1.创建公共组件MyBread.vue <tem ...

  8. Vue 获取验证码倒计时组件

    子组件 <template> <a class="getvalidate":class="{gray: (!stop)}"@click='cl ...

  9. Vue第一个自定义组件:数字输入框(number-input)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

随机推荐

  1. DLL/EXE查看工具Dumpbin

    一般情况下,我们需要查看一个DLL或EXE中的包含的函数或是依赖的函数之类的信息,可以使用VS自带的工具dumpbin: 可以直接在命令行下输入dumpbin就可以查看他的使用说明,如果未显示,可以先 ...

  2. Linux系统实现ansible自动化安装配置httpd

    1.使用ansible的playbook实现自动化安装httpd 1)首先配置好ansible的hosts文件,让其对应主机能够受ansible控制 提示:我们在主机清单上配置了所管控的主机地址,但是 ...

  3. (二)MyBatis延迟加载,一级缓存,二级缓存

    延迟加载配置: 什么时候用延迟加载?比如现在有班级和学生表,一对多关系,你可能只需要班级的信息,而不需要该班级学生的信息,这时候可以进行配置,让查询时先查询到班级的信息,在之后需要学生信息时候,再进行 ...

  4. 磁盘文件系统管理与LVM逻辑卷

    一.磁盘以及分区管理 无论是Linux系统还是Windows系统.当现有硬盘的规划不能满足当前需求时.我们就需要将其重新规划和调整 实现上述操作我们就需要用到fdisk磁盘及分区管理工具.此工具是大多 ...

  5. spark 性能优化 数据倾斜 故障排除

    版本:V2.0 第一章       Spark 性能调优 1.1      常规性能调优 1.1.1   常规性能调优一:最优资源配置 Spark性能调优的第一步,就是为任务分配更多的资源,在一定范围 ...

  6. Windows+Python+Selenium基础篇之1-环境搭建

    1.所需工具包1.1Selenium for python1.2  Python  1.3  Notepad++或python IDE 2.  环境搭建2.1  下载和安装Pythonpython2. ...

  7. Windows渗透备忘录

    Windows渗透备忘录 mimikatz mimikatz.exe ""privilege::debug"" ""sekurlsa::lo ...

  8. ISO14229系列之二:诊断指令格式和相关概念

    作者:autogeek 原文链接:http://www.cnblogs.com/autogeek/p/4458658.html 1. 简单的通信机制 其实诊断通信的机制很简单,可以类比client-s ...

  9. 【WPF学习】第四十九章 基本动画

    在前一章已经学习过WPF动画的第一条规则——每个动画依赖于一个依赖项属性.然而,还有另一个限制.为了实现属性的动态化(换句话说,使用基于时间的方式改变属性的值),需要有支持相应数据类型的动画类.例如, ...

  10. Centos7 使用Docker 部署mssql 2017

    mssql是.NET的标配,一般使用.NET的人基本都用mssql. 以前mssql只能支持windows平台,从微软打出 拥抱开源 的口号开始,mssql的2017 版本,开始支持linux系统. ...