一、页面效果
二、实现
1、视图层
<el-form-item class="flex flex-between">
<el-checkbox label="记住密码" v-model="remember" />
</el-form-item>
参考
Checkbox 多选框 | Element Plus
2、逻辑层
首先设置记住密码的变量,默认值为否。
勾选后,在执行登录成功后,将记住的账号密码存入缓存。(密码的存取需要用到密码加密与解密)
如果记住密码,进入登录页面将账号密码自动显示到账号框和密码框,并且勾选记住密码
①设置变量
const remember = ref(false)
②封装解密加密方法
安装crypto-js
库
npm install crypto-js
这里使用AES(Advanced Encryption Standard) 加密算法
建立页面src/utils/encrypt.js
// 引入方法
import CryptoJS from 'crypto-js';
// 加密密钥(建议存储在环境变量中)
const SECRET_KEY = 'cmskey-QWERTYUIOPASDFGHJKLZXCVBNM';
// 加密函数
export function encryptData(data) {
return CryptoJS.AES.encrypt(JSON.stringify(data), SECRET_KEY).toString();
}
// 解密函数
export function decryptData(encryptedData) {
const bytes = CryptoJS.AES.decrypt(encryptedData, SECRET_KEY);
return JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
}
③封装记住密码的本地存储管理
建立页面src/utils/logininfo.js
- 存入缓存:正常传递的参数是一个对象{username:'',password:''},先对密码进行加密,然后转换为字符串进行存入缓存
- 取出缓存:首先从缓存中获取,获取之后需要将字符串转换为对象,然后将加密的密码进行解密,将设置的新对象进行返回。如果没获取到,清除之前存储的数据
- 删除缓存:根据名称清除记住密码的缓存
//引入加密和解密方法
import { encryptData,decryptData } from '@/utils/encrypt';
//设置变量
const rememberMeKey = 'rememberMe';
//将需要记住的账号密码存入本地缓存
export function setLoginInfo(loginInfo) {
//密码加密
loginInfo.password = encryptData(loginInfo.password);
//将对象转换为字符串
loginInfo = JSON.stringify(loginInfo);
//设置到本地缓存
localStorage.setItem(rememberMeKey, loginInfo);
}
//获取账号密码
export function getLoginInfo() {
//获取账号密码
const loginInfo = localStorage.getItem(rememberMeKey);
//判断是否为空
if (loginInfo) {
//不为空,返回账号密码
//转换为对象
const LoginBase = JSON.parse(loginInfo);
//对密码进行解密
LoginBase.password = decryptData(LoginBase.password);
return LoginBase;
}
else{
//如果没有账号密码,清空之前存的,也就是返回空
removeLoginInfo();
}
}
//删除记住的账号密码
export function removeLoginInfo() {
localStorage.removeItem(rememberMeKey);
}
④登录成功后,将记住的密码存入缓存
//勾选了记住密码
if(remember){
setLoginInfo({
username: ruleForm.username,
password: ruleForm.password
});
}
else{
removeLoginInfo();
}
⑤ 记住密码的默认设置
//获取记住密码的数据
const rememberInfo = getLoginInfo();
if(remember){
//将账号密码设置到页面,并勾选多选框
ruleForm.username = rememberInfo.username;
ruleForm.username = rememberInfo.username;
remember.value = true;
}
三、测试效果
登录前记录缓存-没有账号密码信息
登录成功后,查询本地缓存
成功进入页面,查看是否记录到页面
取消勾选,查看缓存是否清空
发现已经清空缓存
重新进入登录页面,查看页面信息是否清除
四、完整代码
1、登录页面
LoginView.vue
<template>
<div class="page_all flex flex-center">
<div class="login_all flex flex-between">
<div class="login_left flex flex-center"><img src="/svg/login.png"></div>
<div class="login_right flex flex-center flex-column">
<div class="form flex flex-center flex-column">
<div class="title flex flex-center">CMS管理系统</div>
<el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" class="el-form demo-ruleForm"
:size="formSize" status-icon>
<el-form-item prop="username">
<el-input v-model="ruleForm.username" placeholder="请输入账号" />
</el-form-item>
<el-form-item prop="password">
<el-input v-model="ruleForm.password" show-password placeholder="请输入密码" />
</el-form-item>
<el-form-item class="flex flex-between">
<el-checkbox label="记住密码" v-model="remember" />
</el-form-item>
<el-form-item class="btn-group">
<el-button type="primary" @click="submitForm(ruleFormRef)">
登录
</el-button>
<el-button @click="resetForm(ruleFormRef)">重置</el-button>
</el-form-item>
</el-form>
</div>
</div>
</div>
</div>
</template>
<script setup>
//引入方法
import { reactive, ref } from 'vue' //引入vue响应式
import { login } from '@/api/logininfo' //引入登录接口
import { useRouter } from 'vue-router' //引入路由
import { ElMessage } from 'element-plus' //引入提示框
import { setToken } from '@/utils/token' //引入token设置
import { getLoginInfo, removeLoginInfo, setLoginInfo } from '@/utils/logininfo'
//设置表单大小
const formSize = ref('default')
//设置表单数据
const ruleFormRef = ref()
const ruleForm = reactive({
username: '',
password: '',
})
//设置路由
const router = useRouter();
//设置验证规则
const rules = reactive({
username: [
{ required: true, message: '请输入账号', trigger: 'blur' },
{ min: 3, max: 10, message: '长度请在3-10之间', trigger: 'blur' },
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, max: 20, message: '长度请在6-20之间', trigger: 'blur' },
{
validator: (rule, value, callback) => {
const passwordPattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]+$/;
if (!passwordPattern.test(value)) {
callback(new Error('密码必须包含大写字母、小写字母、数字和特殊字符'));
} else {
callback();
}
}, trigger: 'blur'
},
// 或者
// {pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]+$/, message: '密码必须包含大写字母、小写字母、数字和特殊字符', trigger: 'blur'}
],
})
//设置记住密码
const remember = ref(false)
//获取记住密码的数据
const rememberInfo = getLoginInfo();
if(remember){
//将账号密码设置到页面,并勾选多选框
ruleForm.username = rememberInfo.username;
ruleForm.username = rememberInfo.username;
remember.value = true;
}
//表单提交
const submitForm = async (formEl) => {
if (!formEl) return
await formEl.validate((valid, fields) => {
if (valid) {
console.log('submit!');
// 1、请求登录接口进行登录
// 参数为ruleForm
console.log(ruleForm)
// 2、请求登录接口进行登录
login( ruleForm ).then(res => {
console.log('res:', res)
if (res.code == 1) {
// 3、提示成功信息
ElMessage.success(res.msg || '登录成功')
//记住密码勾选
if(remember){
setLoginInfo({
username: ruleForm.username,
password: ruleForm.password
});
}
else{
removeLoginInfo();
}
//存入该账号的token
setToken(res.data.token)
// 4、跳转页面
router.push('/')
}
else {
ElMessage.error(res.msg || '登录失败')
}
})
} else {
console.log('error submit!', fields)
}
})
}
//重置表单
const resetForm = (formEl) => {
if (!formEl) return
formEl.resetFields()
}
</script>
<style>
.page_all {
width: 100%;
height: 100vh;
background-color: #808cdd;
}
.login_all {
width: 50%;
height: 60%;
background-color: white;
}
.login_left {
width: 50%;
height: 98%;
}
.login_left img {
width: 95%;
height: 80%;
object-fit: contain;
}
.login_right {
width: 50%;
height: 100%;
}
.title {
font-size: 25px;
color: #646cff;
letter-spacing: 3px;
height: 20%;
}
.form {
flex: 1;
width: 90%;
}
.el-form {
width: 60%;
}
.el-input__inner {
font-size: 12px;
}
.btn-group {
width: 100%;
margin-top: 30px;
}
.btn-group button {
width: 45%;
}
.el-form-item__content {
justify-content: space-between;
}
</style>
2、记住密码的本地存储管理
src/utils/logininfo
import { encryptData,decryptData } from '@/utils/encrypt';
//设置变量
const rememberMeKey = 'rememberMe';
//将需要记住的账号密码存入本地缓存
export function setLoginInfo(loginInfo) {
//密码加密
loginInfo.password = encryptData(loginInfo.password);
//将对象转换为字符串
loginInfo = JSON.stringify(loginInfo);
//设置到本地缓存
localStorage.setItem(rememberMeKey, loginInfo);
}
//获取账号密码
export function getLoginInfo() {
//获取账号密码
const loginInfo = localStorage.getItem(rememberMeKey);
//判断是否为空
if (loginInfo) {
//不为空,返回账号密码
//转换为对象
const LoginBase = JSON.parse(loginInfo);
//对密码进行解密
LoginBase.password = decryptData(LoginBase.password);
return LoginBase;
}
else{
//如果没有账号密码,清空之前存的,也就是返回空
removeLoginInfo();
}
}
export function removeLoginInfo() {
localStorage.removeItem(rememberMeKey);
}
3、加密解密
// src/utils/encrypt.js
import CryptoJS from 'crypto-js';
// 加密密钥(建议存储在环境变量中)
const SECRET_KEY = 'cmskey-QWERTYUIOPASDFGHJKLZXCVBNM';
// 加密函数
export function encryptData(data) {
return CryptoJS.AES.encrypt(JSON.stringify(data), SECRET_KEY).toString();
}
// 解密函数
export function decryptData(encryptedData) {
const bytes = CryptoJS.AES.decrypt(encryptedData, SECRET_KEY);
return JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
}