vue登录页+验证码+MD5加密
一,验证码功能
1,创建一个组件。显示验证码图片
<template><div class="s-canvas">
<canvas id="s-canvas" :width="contentWidth" :height="contentHeight"></canvas>
</div>
</template>
<script>
export default{
name: 'SIdentify',
props: {
identifyCode: { // 默认注册码
type: String,
default: '1234'
},
fontSizeMin: { // 字体最小值
type: Number,
default: 25
},
fontSizeMax: { // 字体最大值
type: Number,
default: 35
},
backgroundColorMin: { // 验证码图片背景色最小值
type: Number,
default: 200
},
backgroundColorMax: { // 验证码图片背景色最大值
type: Number,
default: 220
},
dotColorMin: { // 背景干扰点最小值
type: Number,
default: 60
},
dotColorMax: { // 背景干扰点最大值
type: Number,
default: 120
},
contentWidth: { // 容器宽度
type: Number,
default: 90
},
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 = '#e6ecfd'
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(50, 160) // 随机生成字体颜色
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(-30, 30)
// 修改坐标原点和旋转角度
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 < 4; i++) {
ctx.strokeStyle = this.randomColor(100, 200)
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 < 30; 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>
2,在登录页面中 验证码输输入框
<el-form-item prop="verificationCode"><el-input type="text" v-model="loginForm.verificationCode" placeholder="- - - -">
<template slot="prepend">验证码</template>
<template slot="append">
<div class="login-code" @click="refreshCode">
<Identify :identifyCode="identifyCode"></Identify>
</div>
</template>
</el-input>
</el-form-item>
//引入验证码组件
import Identify from './identify'
3,登录按钮
<el-button-group><el-button style="width:100%" @click="handleLogin" type="primary">登录</el-button>
</el-button-group>
4,在data中
data() {const validateUsername = (rule, value, callback) => {
if (!value) {
callback(new Error("请输入用户名"));
} else {
callback();
}
};
const validatePassword = (rule, value, callback) => {
if (!value) {
callback(new Error("请输入密码"));
} else {
callback();
}
};
const validateCode = (rule, value, callback) => {
if (value.toLowerCase() !== this.identifyCode.toLowerCase()) {
this.refreshCode();
callback(new Error("请填写正确验证码"));
} else {
callback();
}
};
return {
loginForm: {
username: "",
password: "",
verificationCode: ""
},
loginRules: {
username: [
{ required: true, trigger: "blur", validator: validateUsername }
],
password: [
{ required: true, trigger: "blur", validator: validatePassword }
],
verificationCode: [
{ required: true, trigger: "blur", validator: validateCode }
]
},
passwordType: "password",
capsTooltip: false,
loading: false,
identifyCodes: "1234567890abcdefjhijklinopqrsduvwxyz",
identifyCode: ""
};
},
5,在mounted中
mounted () {// 初始化验证码
this.identifyCode = ''
this.makeCode(this.identifyCodes, 4)
},
6,在method中
//验证码事件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)
];
}
},
randomNum(min, max) {
return Math.floor(Math.random() * (max - min) + min);
},
//登录事件
hhandleLogin(formName) {
let paramt = {
username: this.loginForm.username,
password: this.$md5(this.loginForm.password)
};
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true;
this.$store.dispatch("Login/getLogin", paramt).then(res => {
let userList = res.data.data;
sessionStorage.setItem("token", res.data.data.token);
this.$router.push("/layout");
this.loading = false;
})
.catch(() => {
this.loading = false;
});
} else {
console.log("error submit!!");
return false;
}
});
},
二,MD5加密
1、npm安装
npm install --save js-md5
2,第一种使用方法
在需要使用的项目文件中引入:import md5 from 'js-md5';
使用:
md5('mima')//612341288a285f5b188163482320e88f
3,第二种使用方法
在main.js文件中将md5转换成vue原型:import md5 from 'js-md5';
Vue.prototype.$md5 = md5;
在需要用到的文件中使用:
this.$md5('mima')//612341288a285f5b188163482320e88f
最后附登录页完整代码
<template><div class="login-container">
<nav></nav>
<main>
<div class="main-l"></div>
<div class="main-r">
<img src="../../assets/image/l-t.png" alt />
<div class="form-login">
<el-form
ref="loginForm"
:model="loginForm"
:rules="loginRules"
class="login-form"
autocomplete="on"
label-position="left"
>
<el-form-item prop="username">
<span class="svg-container">
<i class="el-icon-user"></i>
</span>
<el-input
ref="username"
v-model="loginForm.username"
placeholder="请输入用户名"
name="username"
type="text"
tabindex="1"
autocomplete="on"
/>
</el-form-item>
<el-tooltip v-model="capsTooltip" content="Caps lock is On" placement="right" manual>
<el-form-item prop="password">
<span class="svg-container">
<i class="el-icon-lock"></i>
</span>
<el-input
:key="passwordType"
ref="password"
v-model="loginForm.password"
:type="passwordType"
placeholder="请输入密码"
name="password"
tabindex="2"
autocomplete="on"
@keyup.native="checkCapslock"
@blur="capsTooltip = false"
@keyup.enter.native="handleLogin"
/>
<span class="show-pwd" @click="showPwd">
<i
:class="passwordType === 'password' ? 'iconfont zhzyguanbi-yanjing' : 'el-icon-view'"
></i>
</span>
</el-form-item>
</el-tooltip>
<el-form-item prop="verificationCode">
<span class="svg-container">
<i class="el-icon-key"></i>
</span>
<el-input
ref="verificationCode"
v-model="loginForm.verificationCode"
placeholder="请输入验证码"
name="verificationCode"
type="text"
tabindex="1"
autocomplete="on"
>
<template slot="append">
<div class="login-code" @click="refreshCode">
<Identify :identifyCode="identifyCode"></Identify>
</div>
</template>
</el-input>
</el-form-item>
<el-button
:loading="loading"
type="primary"
style="width:100%;height:60px;font-size:20px"
@click.native.prevent="handleLogin"
>立即登录</el-button>
</el-form>
</div>
</div>
</main>
</div>
</template>
<script>
import Identify from "../../components/VerificationCode/VerificationCode";
import { login } from "../../api/login";
import { mapActions } from "vuex";
export default {
name: "Login",
components: { Identify },
data() {
const validateUsername = (rule, value, callback) => {
if (!value) {
callback(new Error("请输入用户名"));
} else {
callback();
}
};
const validatePassword = (rule, value, callback) => {
if (!value) {
callback(new Error("请输入密码"));
} else {
callback();
}
};
const validateCode = (rule, value, callback) => {
if (value.toLowerCase() !== this.identifyCode.toLowerCase()) {
this.refreshCode();
callback(new Error("请填写正确验证码"));
} else {
callback();
}
};
return {
loginForm: {
username: "",
password: "",
verificationCode: ""
},
loginRules: {
username: [
{ required: true, trigger: "blur", validator: validateUsername }
],
password: [
{ required: true, trigger: "blur", validator: validatePassword }
],
verificationCode: [
{ required: true, trigger: "blur", validator: validateCode }
]
},
passwordType: "password",
capsTooltip: false,
loading: false,
identifyCodes: "1234567890abcdefjhijklinopqrsduvwxyz",
identifyCode: ""
};
},
created() {},
mounted() {
if (this.loginForm.username === "") {
this.$refs.username.focus();
} else if (this.loginForm.password === "") {
this.$refs.password.focus();
}
// 初始化验证码
this.identifyCode = "";
this.makeCode(this.identifyCodes, 4);
},
methods: {
checkCapslock({ shiftKey, key } = {}) {
if (key && key.length === 1) {
if (
(shiftKey && (key >= "a" && key <= "z")) ||
(!shiftKey && (key >= "A" && key <= "Z"))
) {
this.capsTooltip = true;
} else {
this.capsTooltip = false;
}
}
if (key === "CapsLock" && this.capsTooltip === true) {
this.capsTooltip = false;
}
},
showPwd() {
if (this.passwordType === "password") {
this.passwordType = "";
} else {
this.passwordType = "password";
}
this.$nextTick(() => {
this.$refs.password.focus();
});
},
handleLogin(formName) {
let paramt = {
username: this.loginForm.username,
password: this.$md5(this.loginForm.password)
};
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true;
this.$store.dispatch("Login/getLogin", paramt).then(res => {
let userList = res.data.data;
sessionStorage.setItem("token", res.data.data.token);
//vuex中的数据刷新页面会消失
this.$router.push("/layout");
this.loading = false;
})
.catch(() => {
this.loading = false;
});
} else {
console.log("error submit!!");
return false;
}
});
},
//验证码事件
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)
];
}
},
randomNum(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
}
};
</script>
<style lang="scss">
/* 修复input 背景不协调 和光标变色 */
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
$bg: #283443;
$light_gray: #fff;
$cursor: #fff;
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
.login-container .el-input input {
color: $cursor;
}
}
/* reset element-ui css */
.login-container {
.el-input {
display: inline-block;
height: 47px;
width: 85%;
input {
background: transparent;
border: 0px;
-webkit-appearance: none;
border-radius: 0px;
padding: 12px 5px 12px 15px;
color: $light_gray;
height: 47px;
caret-color: $cursor;
&:-webkit-autofill {
box-shadow: 0 0 0px 1000px $bg inset !important;
-webkit-text-fill-color: $cursor !important;
}
}
}
.el-form-item {
border: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(0, 0, 0, 0.1);
border-radius: 5px;
color: #454545;
}
nav {
width: 555px;
height: 80px;
background: pink;
margin: 0 auto;
margin-top: 150px;
margin-bottom: 30px;
background: url("../../assets/image/login-text.png") center no-repeat;
}
main {
width: 910px;
height: 505px;
background: url("../../assets/image/l-code.png") center no-repeat;
margin: 0 auto;
display: flex;
.main-l {
width: 390px;
height: 505px;
}
.main-r {
width: 520px;
height: 505px;
padding: 50px 60px 0 55px;
box-sizing: border-box;
.form-login {
margin-top: 30px;
}
.login-code {
width: 90px;
background: rgda(0, 0, 0, 0.6);
}
}
}
}
</style>
<style lang="scss" scoped>
$bg: #2d3a4b;
$dark_gray: #889aa4;
$light_gray: #eee;
.login-container {
width: 100%;
min-height: calc(100vh);
background: url("../../assets/image/l-bge.png") center no-repeat;
overflow: hidden;
.login-form {
position: relative;
width: 520px;
max-width: 100%;
margin: 0 auto;
overflow: hidden;
}
.tips {
font-size: 14px;
color: #fff;
margin-bottom: 10px;
span {
&:first-of-type {
margin-right: 16px;
}
}
}
.svg-container {
padding: 6px 5px 6px 15px;
color: $dark_gray;
vertical-align: middle;
width: 30px;
display: inline-block;
}
.title-container {
position: relative;
.title {
font-size: 26px;
color: $light_gray;
margin: 0px auto 40px auto;
text-align: center;
font-weight: bold;
}
}
.show-pwd {
position: absolute;
right: 10px;
top: 7px;
font-size: 16px;
color: $dark_gray;
cursor: pointer;
user-select: none;
}
.thirdparty-button {
position: absolute;
right: 0;
bottom: 6px;
}
@media only screen and (max-width: 470px) {
.thirdparty-button {
display: none;
}
}
}
</style>
<style lang="scss">
.form-login .el-input-group__append {
background: rgba(0, 0, 0, 0.3);
padding: 0;
left: 260px;
bottom: 44px;
}
</style>
在需要使用的项目文件中引入:
import md5 from 'js-md5';
使用:
md5('mima')//612341288a285f5b188163482320e88f
以上是 vue登录页+验证码+MD5加密 的全部内容, 来源链接: utcz.com/z/380822.html