案例效果
本案例基于 vue.js 和 Element UI 实现。随机验证码采用 DOM 操作和 canvas 绘制,可随机生成和刷新;后续程序逻辑直接填入方法即可。
Element UI 下载安装
//npm安装element npm i element-ui -S //vue项目中全局引入 src/main.js中 import ElementUI from 'element-ui'; Vue.use(ElementUI);
element ui 的使用方式参见官网:
Element - The world's most popular Vue UI framework
Element,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库
https://element.eleme.cn/#/zh-CN
完整代码+详细注释
<template> <div> <div class="login"> <p>登录表单</p> <div class="form"> <!--用户名--> <div class="userAndPass"> <el-input class="txt" v-model="user" placeholder="用户名"></el-input> </div> <!--密码--> <div class="userAndPass"> <el-input class="txt" type="password" v-model="pwd" placeholder="密码"></el-input> </div> <!--验证码--> <div class="userAndPass"> <el-input class="txt" type="text" v-model="code" placeholder="验证码"></el-input> </div> <!--验证码区域--> <div id="codeBox"> <canvas width="112" height="38" id="verifyCanvas"></canvas> </div> <!--验证码生成的图片--> <img id="code_img" @click="refreshCode"> <div style="display: flex;"> <!--记住密码--> <div class="remember" @click="rem"> <img v-show="isRem" src="/static/login_new1/Select%20Reveal.png" alt=""> <div v-show="notRem" style="width: 0.2rem;height: 0.2rem;background-color: white;border-radius: 50%;margin-right: 0.05rem"></div> 记住密码 </div> <!--登录按钮--> <div class="btn" @click="login"> <p>登录</p> </div> </div> <p @click="forget" class="forget">忘记密码?</p> </div> </div> </div> </template> <script> export default { data() { return { user: '', //用户名 pwd: '', //密码 code: '', //用户输入的验证码 rand: [], //随机生成的验证码 isRem: false,//记住密码 notRem: true, //不记住密码(默认此选项) codeList: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'], //随机验证码可选字母 } }, methods: { //点击登录 login() { //验证码的验证 var randStr = this.rand.toString().replace(/,/g, ""); //随机生成的验证码为数组形式,此处将其转为字符串并去掉中间相隔的逗号 var codeStr = this.code; //用户输入的验证码 if (randStr.toLowerCase() == codeStr.toLowerCase()) { //比较用户输入的与随机生成的验证码,不区分大小写 this.$message.success('验证码正确,可正常登录') } else { this.$message.error('请输入正确的验证码'); } //点击登录后的程序逻辑... }, //是否记住密码 rem() { //记住密码 if (this.notRem == true) { this.notRem = false; this.isRem = true; //... } else { //不记住密码 this.notRem = true; this.isRem = false; //... } }, //忘记密码 forget() { console.log("忘记密码"); //忘记密码后的程序逻辑... }, //绘制验证码 drawCode() { //获取canvas画布 var canvas = document.getElementById('verifyCanvas'); var context = canvas.getContext('2d'); //填充画布 context.fillStyle = 'cornflowerblue'; context.fillRect(0, 0, canvas.width, canvas.height); //创建渐变 var gradient = context.createLinearGradient(0, 0, canvas.width, 0); gradient.addColorStop('0', 'yellow'); gradient.addColorStop('0.5', 'black'); gradient.addColorStop('1.0', 'red'); //字体 context.fillStyle = gradient; context.font = '30px Arial'; //验证码的位置 var x = []; var y = []; for (let i = 0; i < 4; i++) { this.rand[i] = this.codeList[Math.floor(Math.random() * this.codeList.length)]; x[i] = i * 26 + 10; y[i] = 30; context.fillText(this.rand[i], x[i], y[i]) } //绘制若干随机点 for (let i = 0; i < 20; i++) { this.drawDot(canvas, context) } this.convertCanvasToImage(canvas); console.log(this.rand); }, drawDot(canvas, context) { var px = Math.floor(Math.random() * canvas.width); var py = Math.floor(Math.random() * canvas.height); context.moveTo(px, py); context.lineTo(px + 1, py + 1); context.lineWidth = 0.2; context.stroke() }, //绘制图片 convertCanvasToImage(canvas) { document.getElementById('verifyCanvas').style.display = 'none'; var image = document.getElementById('code_img'); image.src = canvas.toDataURL('image/png'); return image }, //刷新验证码 refreshCode() { var renew = document.getElementById('codeBox'); var codeObj = document.getElementById('verifyCanvas'); renew.removeChild(codeObj); var canvas = document.createElement('canvas'); canvas.width = '112'; canvas.height = '38'; canvas.id = 'verifyCanvas'; renew.appendChild(canvas); this.drawCode() } }, mounted() { //调用绘制方法 this.drawCode(); this.refreshCode() } } </script> <style scoped> .login { background-color: #3a92a4; border: 2px solid black; border-radius: 10px; width: 5.5rem; height: 5.4rem; margin: auto; } .login > p { float: left; color: white; font-family: "Agency FB"; font-size: 25px; font-weight: bolder; margin: 15px 15px; } /*表单区域*/ .form { width: 80%; height: 90%; margin: 1.1rem auto; } .form .userAndPass { margin-bottom: 0.5rem; } /*验证码图片*/ .form #code_img { position: absolute; top: 4.31rem; width: 1.1rem; height: 0.5rem; border: 1px solid #7EDDB4; left: 10.63rem; cursor: pointer; background-color: #E6F9F2; border-radius: 5px; } .userAndPass .txt /deep/ .el-input__inner { border-radius: 5px !important; height: 0.6rem; } /*记住密码*/ .remember { cursor: pointer; width: 50%; display: flex; font-family: SourceHanSansCN-Regular; font-size: 14px; color: #FFFFFF; letter-spacing: 1.29px; font-weight: 400; margin: auto; line-height: 0.2rem; } .remember img { width: 0.2rem; height: 0.2rem; vertical-align: middle; margin-right: 0.05rem; } /*登录按钮*/ .btn { cursor: pointer; width: 65%; height: 0.6rem; text-align: center; position: relative; display: flex; font-family: SourceHanSansCN-Bold; font-size: 20px; color: #FFFFFF; letter-spacing: 2.85px; background-color: #4ec5f0; border-radius: 5px; } .btn p { margin: auto; line-height: 0.6rem; } .btn img { width: 0.15rem; height: 0.15rem; vertical-align: middle; margin-left: 0.4rem; } .forget { cursor: pointer; font-family: SourceHanSansCN-Regular; font-size: 12px; color: #FFFFFF; letter-spacing: 1.12px; text-align: right; margin-top: 0.09rem; } </style>