antd-Vue实现Login登录页面布局-附带验证码验证功能-案例
效果
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>
本文来自博客园,作者:JackieDYH,转载请注明原文链接:https://www.cnblogs.com/JackieDYH/p/17634100.html