以登录界面为例(效果图)
新建验证码组件 SIdentity
<template><divclass="s-canvas"><canvas id="s-canvas":width="contentWidth":height="contentHeight"></canvas></div></template><script>exportdefault{
name:'SIdentify',
props:{
identifyCode:{
type: String,default:'1234'},
fontSizeMin:{
type: Number,default:16},
fontSizeMax:{
type: Number,default:40},
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}},
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(-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)},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()}},drawDot(ctx){// 绘制干扰点for(let i=0; i<100; 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()}},mounted(){this.drawPic()}}</script><style>.s-canvas{
height:38px;}
canvas{
margin-top:1px;
margin-left:8px;}</style>
在所需界面中引入组件(HTML代码如下)
<template><divclass="aric-main"><img src="../assets/thbg.png"><el-form:model="ruleForm" status-icon:rules="rules" ref="ruleForm" label-width="100px"class="demo-ruleForm aric-login-form"><el-form-item label="用户名" prop="username"><el-input placeholder="请输入手机号" v-model.number="ruleForm.username" clearable></el-input></el-form-item><el-form-item label="密码" prop="pass"><el-input placeholder="请输入密码" type="password" v-model="ruleForm.pass" show-password clearable></el-input></el-form-item><el-form-item label="验证码" prop="validate"><el-inputclass="aric-yanzheng" placeholder="请输入验证码" type="text" v-model="ruleForm.validate"></el-input><divclass="login-code" @click="refreshCode"><Identify:identifyCode="identifyCode"></Identify></div></el-form-item><el-form-item><el-button type="primary" @click="submitForm('ruleForm')">提交</el-button><el-button @click="registerClick">注册</el-button><spanclass="aric-foget-btn" @click="Forgetpass">?忘记密码</span></el-form-item></el-form></div></template>
JS代码如下
<script>import Identifyfrom'../components/SIdentity.vue';exportdefault{
name:'login',
template:{},
components:{
Identify},data(){varcheckPhone=(rule, value, callback)=>{if(!value){returncallback(newError('手机号不能为空'));}else{const reg=/^1[3|4|5|7|8][0-9]\d{8}$/
console.log(reg.test(value));if(reg.test(value)){callback();}else{returncallback(newError('手机号格式错误'));}}};constvalidateVerifycode=(rule, value, callback)=>{if(!value){callback(newError('请输入验证码'));}elseif(value!=this.identifyCode){
console.log('validateVerifycode:', value)this.ruleForm.validate=''this.refreshCode()callback(newError('验证码不正确!'));}else{callback();}};return{// isDebugLogin: false,
identifyCodes:'123456789',
identifyCode:'',
ruleForm:{
pass:'',
username:'',
validate:''},
rules:{
username:[// { required: true, message: '请输入用户名', trigger: 'blur' },// { min: 3, max: 8, message: '长度为 3 到 8 个字符', trigger: 'blur' }{ validator: checkPhone, required:true, trigger:'blur'}],
pass:[{ required:true, message:'请输入密码', trigger:'blur'},{ min:6, max:17, message:'长度为 6 到 17 个字符', trigger:'change'}],
validate:[{ validator: validateVerifycode, required:true, trigger:'blur'}]}};},mounted(){// 初始化验证码this.identifyCode=''this.makeCode(this.identifyCodes,4)},
methods:{randomNum(min, max){return Math.floor(Math.random()*(max- min)+ min)},refreshCode(){this.identifyCode=''this.makeCode(this.identifyCodes,4)},makeCode(o, l){for(let i=0; i< l; i++){this.identifyCode+=this.identifyCodes[this.randomNum(0,this.identifyCodes.length)]}},submitForm(formName){this.$refs[formName].validate((valid)=>{
console.log(valid)if(valid){alert('submit!');// 发送请求给后台,请求数据成功之后this.$router.push('/home')}else{
console.log('error submit!!');returnfalse;}});},created(){this.refreshCode()},registerClick(){this.$router.push('/register');},Forgetpass(){this.$router.push('/forget')}}}</script>