目录
完整项目请访问
一.各页面完整代码
1.浏览器缓存相关设置
2.pinia状态管理应用
3.request请求/响应拦截
4.路由守卫
5.登录页代码
6.header登录部分代码
二.部分代码截取
1.login登录页
2.header部分
gitee:vue3-TS-model: 用于从零搭建模板使用 (gitee.com)
github:vue3-TS-model: 用于从零搭建模板使用 (gitee.com)
这一部分使用了localstorage,session,cookies数据缓存方式
import Cookies from 'js-cookie';
/**
* window.localStorage 浏览器永久缓存
* @method set 设置永久缓存
* @method get 获取永久缓存
* @method remove 移除永久缓存
* @method clear 移除全部永久缓存
*/
export const Local = {
// 设置永久缓存
set(key: string, val: any) {
window.localStorage.setItem(key, JSON.stringify(val));
},
// 获取永久缓存
get(key: string) {
let json: any = window.localStorage.getItem(key);
return JSON.parse(json);
},
// 移除永久缓存
remove(key: string) {
window.localStorage.removeItem(key);
},
// 移除全部永久缓存
clear() {
window.localStorage.clear();
},
};
/**
* window.sessionStorage 浏览器临时缓存
* @method set 设置临时缓存
* @method get 获取临时缓存
* @method remove 移除临时缓存
* @method clear 移除全部临时缓存
*/
export const Session = {
// 设置临时缓存
set(key: string, val: any) {
if (key === 'token' || key === 'username'){
const expirationTime = new Date();
expirationTime.setTime(expirationTime.getTime() + 2 * 60 * 60 * 1000); // 2小时后过期
return Cookies.set(key, val, { expires: expirationTime });
}
window.sessionStorage.setItem(key, JSON.stringify(val));
},
// 获取临时缓存
get(key: string) {
if (key === 'token' || key === 'username') return Cookies.get(key);
let json: any = window.sessionStorage.getItem(key);
return JSON.parse(json);
},
// 移除临时缓存
remove(key: string) {
if (key === 'token' || key === 'username') return Cookies.remove(key);
window.sessionStorage.removeItem(key);
},
// 移除全部临时缓存
clear() {
Cookies.remove('token');
Cookies.remove('username');
window.sessionStorage.clear();
},
};
这一部分用于存储登陆后获取的一些信息,用于全局
// 在 src/store/index.js 中创建一个简单的 store
import { UserInfoState } from '@/api/login/types';
import { defineStore } from 'pinia'
interface State {
userForm: UserInfoState;
isLogin:boolean;
}
export const useMyStore = defineStore('myStore', {
state: (): State => ({
userForm: {
user: '',
ID: '',
age: '',
sex: ''
},
isLogin:false
// 其他状态
}),
actions: {
// 动作
setUserInfo(data:UserInfoState) {
this.userForm = data
},
setIsLogin(data:boolean) {
this.isLogin = data
},
},
})
import axios from 'axios';
import { ElMessage, ElMessageBox } from 'element-plus';
import { Session } from '@/utils/storage';
// 配置新建一个 axios 实例
const service = axios.create({
baseURL: 'https://www.fastmock.site/mock/b9536a1dea3fe4daeec18bc365e14a18/api',
timeout: 50000,
headers: { 'Content-Type': 'application/json' },
});
// 添加请求拦截器
service.interceptors.request.use(
(config) => {
// 在发送请求之前做些什么 token
if (Session.get('token')) {
(config.headers).common['token'] = `${Session.get('token')}`;
}
return config;
},
(error) => {
// 对请求错误做些什么
return Promise.reject(error);
}
);
// 添加响应拦截器
service.interceptors.response.use(
(response) => {
// 对响应数据做点什么
const res = response.data;
if (res.code && res.code !== '2000') {
// `token` 过期或者账号已在别处登录
if (res.code === 401 || res.code === "4001") {
Session.clear(); // 清除浏览器全部临时缓存
window.location.href = '/'; // 去登录页
ElMessageBox.alert('你已被登出,请重新登录', '提示', {})
.then(() => {})
.catch(() => {});
}
return response.data;
// return Promise.reject(service.interceptors.response);
} else {
return response.data;
}
},
(error) => {
// 对响应错误做点什么
if (error.message.indexOf('timeout') != -1) {
ElMessage.error('网络超时');
} else if (error.message == 'Network Error') {
ElMessage.error('网络连接错误');
} else {
if (error.response.data) ElMessage.error(error.response.statusText);
else ElMessage.error('接口路径找不到');
}
return Promise.reject(error);
}
);
// 导出 axios 实例
export default service;
// 导入router所需的方法
import { createRouter, createWebHashHistory } from 'vue-router'
// 导入路由页面的配置
import routes from './routes'
import { Session } from '@/utils/storage'
import { useMyStore } from '@/stores/states'
// 路由参数配置
const router = createRouter({
// 使用hash(createWebHashHistory)模式,(createWebHistory是HTML5历史模式,支持SEO)
history: createWebHashHistory(),
routes: routes,
})
// 全局前置守卫,这里可以加入用户登录判断
router.beforeEach((to, from, next) => {
if(Session.get('token') && (from.path === '/' || to.path === '/index')){
useMyStore().setIsLogin(true)
}
// 继续前进 next()
// 返回 false 以取消导航
next()
})
// 全局后置钩子,这里可以加入改变页面标题等操作
router.afterEach((to, from) => {
const _title = to.meta.title
if (_title) {
window.document.title = String(_title)
}
})
// 导出默认值
export default router
登录
登录
XXXXXXXXXXX
XXX系统
// 定义登录逻辑
const login = () => {
let data: LoginState = {
username: state.formData.username,
password: state.formData.password,
code: state.formData.code
}
useLoginApi.login(data)
.then((res) => {
console.log(res);
// 登录成功后的处理逻辑
Session.set('token', res.data.token)
Session.set('username', res.data.userInfo.user)
useUserInfoStore.setUserInfo(res.data.userInfo)
useUserInfoStore.setIsLogin(true)
router.push({
name: 'index'
})
})
.catch((err) => {
console.log(err);
})
}
// 退出登录
const logout = (pageUrl: string) => {
console.log('logout', pageUrl);
// 弹出确认对话框
ElMessageBox.confirm(
'确认退出登录?',
'提示',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
// 清空本地存储
Session.clear();
// 设置全局状态中的登录状态为 false
useMyStore().setIsLogin(false);
// 跳转到指定页面
router.push({ name: pageUrl });
// 提示退出成功
ElMessage({
type: 'success',
message: '退出成功!',
});
})
.catch(() => {
// 提示取消退出
ElMessage({
type: 'info',
message: '取消退出!',
});
});
};