在依赖安装部分,我们使用更好用的 Pinia 替代 Vuex,并进行了基础的配置。
该部分我们添加一点些需要进行状态管理的对象。
常量
创建src/store/mutation-types.js
,写入以下内容:
store/mutation-types.jsexport const ACCESS_TOKEN = 'ACCESS-TOKEN'; export const CURRENT_USER = 'CURRENT-USER'; export const TABS_ROUTES = 'TABS-ROUTES';
|
用户状态管理
值得注意的是,登陆和获取用户信息的请求是在此处发起的。
网络请求方法:getUserInfo, login将在网络配置部分予以实现,这里为了不报错可实现两个空方法。
创建src/store/modules/user.js
,写入以下内容:
store/modules/user.jsimport { storage } from '@/utils/Storage'; import { defineStore } from 'pinia'; import { store } from '@/store'; import { ACCESS_TOKEN, CURRENT_USER } from '../mutation-types'; import { getUserInfo, login } from '@/api/system/user'; import { ResultEnum } from '@/enums/httpEnum';
export const useUserStore = defineStore({ id: 'app-user', state: () => ({ token: storage.get(ACCESS_TOKEN, ''), username: '', welcome: '', avatar: '', permissions: [], info: storage.get(CURRENT_USER, {}), }), getters: { getToken() { return this.token; }, getAvatar() { return this.avatar; }, getNickname() { return this.username; }, getPermissions() { return this.permissions; }, getUserInfo() { return this.info; }, }, actions: { setToken(token) { this.token = token; }, setAvatar(avatar) { this.avatar = avatar; }, setPermissions(permissions) { this.permissions = permissions; }, setUserInfo(info) { this.info = info; }, async login(userInfo) { try { const response = await login(userInfo); const { data: result, code } = response; if (code === ResultEnum.SUCCESS) { const ex = 7 * 24 * 60 * 60; storage.set(ACCESS_TOKEN, result.token, ex); storage.set(CURRENT_USER, result, ex); this.setToken(result.token); this.setUserInfo(result); } return Promise.resolve(response); } catch (e) { return Promise.reject(e); } },
GetInfo() { const that = this; return new Promise((resolve, reject) => { getUserInfo() .then((res) => { const result = res; if (result.permissions && result.permissions.length) { const permissionsList = result.permissions; that.setPermissions(permissionsList); that.setUserInfo(result); } else { reject( new Error('getInfo: permissionsList must be a non-null array !') ); } that.setAvatar(result.avatar); resolve(res); }) .catch((error) => { reject(error); }); }); },
async logout() { this.setPermissions([]); this.setUserInfo(''); storage.remove(ACCESS_TOKEN); storage.remove(CURRENT_USER); return Promise.resolve(''); }, }, });
export function useUserStoreWidthOut() { return useUserStore(store); }
|
标签页状态管理
不使用标签页功能时,可不添加其状态管理
本项目实现了页面标签页以及组件缓存功能。
创建src/store/modules/tabsView.js
,写入以下内容:
store/modules/tabsView.jsimport { defineStore } from 'pinia';
const whiteList = ['Redirect', 'login'];
function retainAffixRoute(list) { return list.filter((item) => item?.meta?.affix ?? false); }
export const useTabsViewStore = defineStore({ id: 'app-tabs-view', state: () => ({ tabsList: [], }), getters: {}, actions: { initTabs(routes) { this.tabsList = routes; }, addTabs(route) { if (whiteList.includes(route.name)) return false; const isExists = this.tabsList.some( (item) => item.fullPath == route.fullPath ); if (!isExists) { this.tabsList.push(route); } return true; }, closeLeftTabs(route) { const index = this.tabsList.findIndex( (item) => item.fullPath == route.fullPath ); this.tabsList = this.tabsList.filter( (item, i) => i >= index || (item?.meta?.affix ?? false) ); }, closeRightTabs(route) { const index = this.tabsList.findIndex( (item) => item.fullPath == route.fullPath ); this.tabsList = this.tabsList.filter( (item, i) => i <= index || (item?.meta?.affix ?? false) ); }, closeOtherTabs(route) { this.tabsList = this.tabsList.filter( (item) => item.fullPath == route.fullPath || (item?.meta?.affix ?? false) ); }, closeCurrentTab(route) { const index = this.tabsList.findIndex( (item) => item.fullPath == route.fullPath ); this.tabsList.splice(index, 1); }, closeAllTabs() { console.log(retainAffixRoute(this.tabsList)); this.tabsList = retainAffixRoute(this.tabsList); }, }, });
|