antd Vue实现Login登录页面布局案例详解 附带验证码验证功能
时间:2022-11-27 10:22:22|栏目:vue|点击: 次
效果
Login页面
<!-- * @Author: Jackie * @Date: 2022-05-07 14:34:06 * @LastEditTime: 2022-05-09 15:57:44 * @LastEditors: Jackie * @Description: 登录页 用户名-密码-验证码登录方式 * @FilePath: /vue-admin-template/src/views/Login.vue * @version: --> <template> <div class="Login"> <h1 class="title">JackieDYH管理平台</h1> <a-form-model ref="ruleForm" :model="form" :rules="rules"> <h5>登录</h5> <a-form-model-item prop="name"> <a-input v-model="form.name" placeholder="请输入邮箱/手机号" /> </a-form-model-item> <a-form-model-item prop="password"> <a-input type="password" v-model="form.password" placeholder="请输入密码" /> </a-form-model-item> <a-form-model-item prop="code" class="identify"> <a-input v-model="form.code" placeholder="请输入验证码" /> <Identify :identifyCode="identifyCode" @click="refreshCode" /> </a-form-model-item> <a-form-model-item> <a-button block type="primary" @click="onSubmit"> 提交 </a-button> <!-- <router-link :to="{ name: 'Password' }" style="float: right" class="pointer" > 忘记密码 </router-link> --> </a-form-model-item> </a-form-model> </div> </template> <script> import Identify from "@/components/Identify"; export default { name: "Login", components: { Identify }, data() { let validateCode = (rule, value, callback) => { if (value === "") { callback(new Error("验证码为空")); return false; } else if (value !== this.identifyCode) { callback(new Error("验证码不正确")); return false; } else { callback(); } }; return { identifyCodes: "1234567890", identifyCode: "", form: { name: "", password: "", code: "", }, rules: { name: { required: true, message: "请输入邮箱/手机号", trigger: "blur" }, password: { required: true, message: "请输入密码", trigger: "blur" }, code: [{ validator: validateCode, trigger: "blur" }], }, }; }, mounted() { // 初始 this.identifyCode = ""; this.makeCode(this.identifyCodes, 4); }, methods: { // 确认 onSubmit() { this.$refs.ruleForm.validate((valid) => { if (valid) { this.$router.push("/home"); } else { console.log("error submit!!"); return false; } }); }, // 重置表单 resetForm() { this.$refs.ruleForm.resetFields(); }, // 验证码相关 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)]; } }, }, }; </script> <style lang="scss" scoped> .Login { width: 100%; height: 100%; background-image: url("~@/assets/images/bg_repeat_white.png"); overflow: auto; .title { font-size: 40px; font-weight: bold; padding: 60px 0 60px 40px; } .ant-form { width: 500px; border-radius: 5px; background: #fff; margin: auto; padding: 18px 40px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); .ant-dropdown-trigger { float: right; margin-right: -20px; } h5 { font-size: 26px; text-align: center; margin-bottom: 25px; } } @media screen and (min-width: 769px) and (max-width: 1000px) { .title { font-size: 50px; text-align: center; } .ant-form { width: 60%; } } @media screen and (max-width: 769px) { .title { font-size: 50px; text-align: center; } .ant-form { width: 90%; } } } </style> <style lang="scss"> // 验证码样式 .Login .identify .ant-form-item-children { display: flex; align-items: center; .ant-input { flex: 1; margin-right: 10px; } } </style>
Identify验证码
<!-- * @Author: Jackie * @Date: 2022-05-09 14:49:38 * @LastEditTime: 2022-05-09 14:49:39 * @LastEditors: Jackie * @Description: 验证码 * @FilePath: /vue-admin-template/src/components/Identify.vue * @version: --> <template> <canvas id="s-canvas" :width="contentWidth" :height="contentHeight" v-on="$listeners" ></canvas> </template> <script> export default { 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 lang="scss"> canvas { cursor: pointer; } </style>