前端使用pinia
引入一下相关的库,pinia和pinia-plugin-persistedstate,pinia-plugin-persistedstate用于数据持久化
yarn add pinia pinia-plugin-persistedstate
创建Store文件
创建src/stores/app.ts
import { ref } from 'vue'
import { defineStore } from 'pinia'
import type { AppTypes } from '@/interface/app/AppTypes'
import type { UserTypes } from '@/interface/user/UserTypes'
export const useAppStore = defineStore('app', () => {
const userMenu = ref<AppTypes.Menu[]>([])//登录用户的权限菜单 1:n
const userDeptList = ref<string[]>([])//登录用户的部门 1:n
const userRoleList = ref<string[]>([])//登录用户的角色 1:n
const userInfo = ref<UserTypes.UserInfo | null>(null)//登录的用户信息
// 设置菜单
const setUserMenu = (list: AppTypes.Menu[]) => {
userMenu.value = list
}
// 设置部门
const setUserDeptList = (list: string[]) => {
userDeptList.value = list
}
// 设置角色
const setUserRoleList = (list: string[]) => {
userRoleList.value = list
}
// 设置用户信息
const setUserInfo = (info: UserTypes.UserInfo) => {
userInfo.value = info
}
return {
userMenu,
userDeptList,
userRoleList,
userInfo,
setUserMenu,
setUserDeptList,
setUserRoleList,
setUserInfo
}
},
{
// 持久化配置
persist: {
key: "app",//持久化的key
storage: window.sessionStorage,//数据存储的
paths: ['userMenu', 'userDeptList', 'userRoleList', 'userInfo']//要存储的key,不配置就存储全部
}
}
)
补充一下类型代码
创建src/interface/app/AppTypes.ts
export namespace AppTypes {
export interface Menu {
id: string
createTime?: string
updateTime?: string
createBy?: string
updateBy?: string
menuCode: string
menuName: string
parentCode: string | null
temPath: string
menuPath: string
visible: 0 | 1
remark: string
status: string
sortNo: number
menuIcon: string
children?: Menu[]
}
}
创建src/interface/user/UserTypes.
export namespace UserTypes {
export interface UserInfo {
id: string
createTime?: string
updateTime?: string
createBy?: string
updateBy?: string
userCode: string
userName: string
avatar: string
sex: 0 | 1
status: string
}
}
在main.ts上引入
import './assets/main.scss'
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import piniaPersist from "pinia-plugin-persistedstate";
import App from './App.vue'
import router from './router'
const app = createApp(App)
const pinia = createPinia()
pinia.use(piniaPersist)
app.use(pinia)
app.use(router)
app.mount('#app')
使用
补充LoginView.ts的登录代码
import { LoginApi } from "@/api/LoginApi"
import type { LoginTypes } from "@/interface/commons/LoginTypes"
import { useAppStore } from "@/stores/app"
import { ref } from "vue"
import JsCookie from "js-cookie"
import { CommonConstants } from "@/constants/CommonConstants"
import { useRouter } from "vue-router"
const defaultLoginView = () => {
const appStore = useAppStore()
const router = useRouter()
// 登录信息
const loginForm = ref<LoginTypes.LoginForm>(localStorage.getItem('loginForm') ? JSON.parse(localStorage.getItem('loginForm')!) : {
userCode: '',
password: "",
remember: false
})
/**
* 前面的代码省略
**/
// 登录事件
const handleLoginBtnClick = () => {
if (!loginForm.value.password || !loginForm.value.userCode) {
ElMessage.error("帐号或者密码不允许为空")
return
} else {
LoginApi.doLogin(loginForm.value).then((result) => {
if (result.code == 200) {
ElMessage.success("登录成功")
if (loginForm.value.remember) {
localStorage.setItem('loginForm', JSON.stringify(loginForm.value))
} else {
localStorage.setItem('loginForm', JSON.stringify({ ...loginForm.value, password: '' }))
}
appStore.setUserMenu(result.data.menu)
appStore.setUserDeptList(result.data.deptList)
appStore.setUserRoleList(result.data.roleList)
appStore.setUserInfo(result.data.userInfo)
JsCookie.set(CommonConstants.TOKEN_KEY, result.data.authToken)
router.replace({ path: result.data.menu[0].menuPath })
} else {
ElMessage.error(result.msg)
}
})
}
}
}
这里只是做了一个写入,读去的等下跳转路由之后做排版再说吧
因为登录之后要做路由跳转,登录的时候token是存到cookie的,之前做的路由拦截是判断在localStorage的,所以改一下路由守卫的判断代码
效果
录屏2024-04-24 08.32.56