refactor: 优化pinia setup store组合式函数写法
Former-commit-id: 27347ede51d0952d3422c3a6c3a86652f91e5639
This commit is contained in:
@@ -1,48 +1,96 @@
|
||||
import { AppState } from './types';
|
||||
import { localStorage } from '@/utils/storage';
|
||||
import {
|
||||
getSidebarStatus,
|
||||
setSidebarStatus,
|
||||
getSize,
|
||||
setSize,
|
||||
setLanguage
|
||||
} from '@/utils/localStorage';
|
||||
import { defineStore } from 'pinia';
|
||||
import { getLanguage } from '@/lang/index';
|
||||
import { computed, reactive, ref } from 'vue';
|
||||
|
||||
const useAppStore = defineStore({
|
||||
id: 'app',
|
||||
state: (): AppState => ({
|
||||
device: 'desktop',
|
||||
sidebar: {
|
||||
opened: localStorage.get('sidebarStatus')
|
||||
? !!+localStorage.get('sidebarStatus')
|
||||
: true,
|
||||
withoutAnimation: false,
|
||||
},
|
||||
language: getLanguage(),
|
||||
size: localStorage.get('size') || 'default',
|
||||
}),
|
||||
actions: {
|
||||
toggleSidebar() {
|
||||
this.sidebar.opened = !this.sidebar.opened;
|
||||
this.sidebar.withoutAnimation = false;
|
||||
if (this.sidebar.opened) {
|
||||
localStorage.set('sidebarStatus', 1);
|
||||
} else {
|
||||
localStorage.set('sidebarStatus', 0);
|
||||
}
|
||||
},
|
||||
closeSideBar(withoutAnimation: any) {
|
||||
localStorage.set('sidebarStatus', 0);
|
||||
this.sidebar.opened = false;
|
||||
this.sidebar.withoutAnimation = withoutAnimation;
|
||||
},
|
||||
toggleDevice(device: string) {
|
||||
this.device = device;
|
||||
},
|
||||
setSize(size: string) {
|
||||
this.size = size;
|
||||
localStorage.set('size', size);
|
||||
},
|
||||
setLanguage(language: string) {
|
||||
this.language = language;
|
||||
localStorage.set('language', language);
|
||||
},
|
||||
},
|
||||
// Element Plus 语言包
|
||||
import zhCn from 'element-plus/es/locale/lang/zh-cn';
|
||||
import en from 'element-plus/es/locale/lang/en';
|
||||
|
||||
export enum DeviceType {
|
||||
mobile,
|
||||
desktop
|
||||
}
|
||||
|
||||
export enum SizeType {
|
||||
default,
|
||||
large,
|
||||
small
|
||||
}
|
||||
|
||||
// setup
|
||||
export const useAppStore = defineStore('app', () => {
|
||||
// state
|
||||
const device = ref<DeviceType>(DeviceType.desktop);
|
||||
const size = ref(getSize() || 'default');
|
||||
const language = ref(getLanguage());
|
||||
const sidebar = reactive({
|
||||
opened: getSidebarStatus() !== 'closed',
|
||||
withoutAnimation: false
|
||||
});
|
||||
|
||||
const locale = computed(() => {
|
||||
if (language?.value == 'en') {
|
||||
return en;
|
||||
} else {
|
||||
return zhCn;
|
||||
}
|
||||
});
|
||||
|
||||
// actions
|
||||
function toggleSidebar(withoutAnimation: boolean) {
|
||||
sidebar.opened = !sidebar.opened;
|
||||
sidebar.withoutAnimation = withoutAnimation;
|
||||
if (sidebar.opened) {
|
||||
setSidebarStatus('opened');
|
||||
} else {
|
||||
setSidebarStatus('closed');
|
||||
}
|
||||
}
|
||||
|
||||
function closeSideBar(withoutAnimation: boolean) {
|
||||
sidebar.opened = false;
|
||||
sidebar.withoutAnimation = withoutAnimation;
|
||||
setSidebarStatus('closed');
|
||||
}
|
||||
|
||||
function openSideBar(withoutAnimation: boolean) {
|
||||
sidebar.opened = true;
|
||||
sidebar.withoutAnimation = withoutAnimation;
|
||||
setSidebarStatus('opened');
|
||||
}
|
||||
|
||||
function toggleDevice(val: DeviceType) {
|
||||
device.value = val;
|
||||
}
|
||||
|
||||
function changeSize(val: string) {
|
||||
size.value = val;
|
||||
setSize(val);
|
||||
}
|
||||
|
||||
function changeLanguage(val: string) {
|
||||
language.value = val;
|
||||
setLanguage(val);
|
||||
}
|
||||
|
||||
return {
|
||||
device,
|
||||
sidebar,
|
||||
language,
|
||||
locale,
|
||||
size,
|
||||
toggleDevice,
|
||||
changeSize,
|
||||
changeLanguage,
|
||||
toggleSidebar,
|
||||
closeSideBar,
|
||||
openSideBar
|
||||
};
|
||||
});
|
||||
|
||||
export default useAppStore;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { PermissionState } from './types';
|
||||
import { RouteRecordRaw } from 'vue-router';
|
||||
import { defineStore } from 'pinia';
|
||||
import { constantRoutes } from '@/router';
|
||||
import { store } from '@/store';
|
||||
import { listRoutes } from '@/api/menu';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const modules = import.meta.glob('../../views/**/**.vue');
|
||||
export const Layout = () => import('@/layout/index.vue');
|
||||
@@ -21,10 +22,7 @@ const hasPermission = (roles: string[], route: RouteRecordRaw) => {
|
||||
return false;
|
||||
};
|
||||
|
||||
export const filterAsyncRoutes = (
|
||||
routes: RouteRecordRaw[],
|
||||
roles: string[]
|
||||
) => {
|
||||
const filterAsyncRoutes = (routes: RouteRecordRaw[], roles: string[]) => {
|
||||
const res: RouteRecordRaw[] = [];
|
||||
routes.forEach(route => {
|
||||
const tmp = { ...route } as any;
|
||||
@@ -49,32 +47,36 @@ export const filterAsyncRoutes = (
|
||||
return res;
|
||||
};
|
||||
|
||||
const usePermissionStore = defineStore({
|
||||
id: 'permission',
|
||||
state: (): PermissionState => ({
|
||||
routes: [],
|
||||
addRoutes: []
|
||||
}),
|
||||
actions: {
|
||||
setRoutes(routes: RouteRecordRaw[]) {
|
||||
this.addRoutes = routes;
|
||||
this.routes = constantRoutes.concat(routes);
|
||||
},
|
||||
generateRoutes(roles: string[]) {
|
||||
return new Promise((resolve, reject) => {
|
||||
listRoutes()
|
||||
.then(response => {
|
||||
const asyncRoutes = response.data;
|
||||
const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles);
|
||||
this.setRoutes(accessedRoutes);
|
||||
resolve(accessedRoutes);
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
// setup
|
||||
export const usePermissionStore = defineStore('permission', () => {
|
||||
// state
|
||||
const routes = ref<RouteRecordRaw[]>([]);
|
||||
const addRoutes = ref<RouteRecordRaw[]>([]);
|
||||
|
||||
// auctions
|
||||
function setRoutes(newRoutes: RouteRecordRaw[]) {
|
||||
addRoutes.value = newRoutes;
|
||||
routes.value = constantRoutes.concat(newRoutes);
|
||||
}
|
||||
|
||||
function generateRoutes(roles: string[]) {
|
||||
return new Promise<RouteRecordRaw[]>((resolve, reject) => {
|
||||
listRoutes()
|
||||
.then(response => {
|
||||
const asyncRoutes = response.data;
|
||||
const accessedRoutes = filterAsyncRoutes(asyncRoutes, roles);
|
||||
setRoutes(accessedRoutes);
|
||||
resolve(accessedRoutes);
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
return { routes, setRoutes, generateRoutes };
|
||||
});
|
||||
|
||||
export default usePermissionStore;
|
||||
// 非setup
|
||||
export function usePermissionStoreHook() {
|
||||
return usePermissionStore(store);
|
||||
}
|
||||
|
||||
@@ -1,50 +1,55 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { SettingState } from './types';
|
||||
import defaultSettings from '../../settings';
|
||||
import { localStorage } from '@/utils/storage';
|
||||
import { localStorage } from '@/utils/localStorage';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const { showSettings, tagsView, fixedHeader, sidebarLogo } = defaultSettings;
|
||||
const el = document.documentElement;
|
||||
|
||||
export const useSettingStore = defineStore({
|
||||
id: 'setting',
|
||||
state: (): SettingState => ({
|
||||
theme:
|
||||
localStorage.get('theme') ||
|
||||
getComputedStyle(el).getPropertyValue(`--el-color-primary`),
|
||||
showSettings: showSettings,
|
||||
tagsView:
|
||||
localStorage.get('tagsView') != null
|
||||
? localStorage.get('tagsView')
|
||||
: tagsView,
|
||||
fixedHeader: fixedHeader,
|
||||
sidebarLogo: sidebarLogo,
|
||||
}),
|
||||
actions: {
|
||||
async changeSetting(payload: { key: string; value: any }) {
|
||||
const { key, value } = payload;
|
||||
switch (key) {
|
||||
case 'theme':
|
||||
this.theme = value;
|
||||
break;
|
||||
case 'showSettings':
|
||||
this.showSettings = value;
|
||||
break;
|
||||
case 'fixedHeader':
|
||||
this.fixedHeader = value;
|
||||
break;
|
||||
case 'tagsView':
|
||||
this.tagsView = value;
|
||||
localStorage.set('tagsView', value);
|
||||
break;
|
||||
case 'sidebarLogo':
|
||||
this.sidebarLogo = value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
export const useSettingsStore = defineStore('setting', () => {
|
||||
// state
|
||||
const theme = ref(
|
||||
localStorage.get('theme') ||
|
||||
getComputedStyle(el).getPropertyValue(`--el-color-primary`)
|
||||
);
|
||||
|
||||
export default useSettingStore;
|
||||
const showSettings = ref<boolean>(defaultSettings.showSettings);
|
||||
const tagsView = ref<boolean>(
|
||||
localStorage.get('tagsView') || defaultSettings.tagsView
|
||||
);
|
||||
const fixedHeader = ref<boolean>(defaultSettings.fixedHeader);
|
||||
const sidebarLogo = ref<boolean>(defaultSettings.sidebarLogo);
|
||||
|
||||
// auction
|
||||
function changeSetting(param: { key: string; value: any }) {
|
||||
const { key, value } = param;
|
||||
switch (key) {
|
||||
case 'theme':
|
||||
theme.value = value;
|
||||
break;
|
||||
case 'showSettings':
|
||||
showSettings.value = value;
|
||||
break;
|
||||
case 'fixedHeader':
|
||||
fixedHeader.value = value;
|
||||
localStorage.set('tagsView', value);
|
||||
break;
|
||||
case 'tagsView':
|
||||
tagsView.value = value;
|
||||
break;
|
||||
case 'sidevarLogo':
|
||||
sidebarLogo.value = value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
theme,
|
||||
showSettings,
|
||||
tagsView,
|
||||
fixedHeader,
|
||||
sidebarLogo,
|
||||
changeSetting
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,181 +1,214 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { TagsViewState } from './types';
|
||||
import { ref } from 'vue';
|
||||
import { RouteLocationNormalized } from 'vue-router';
|
||||
|
||||
const useTagsViewStore = defineStore({
|
||||
id: 'tagsView',
|
||||
state: (): TagsViewState => ({
|
||||
visitedViews: [],
|
||||
cachedViews: [], // keepAlive 缓存页面
|
||||
}),
|
||||
actions: {
|
||||
addVisitedView(view: any) {
|
||||
if (this.visitedViews.some((v) => v.path === view.path)) return;
|
||||
if (view.meta && view.meta.affix) {
|
||||
this.visitedViews.unshift(
|
||||
Object.assign({}, view, {
|
||||
title: view.meta?.title || 'no-name',
|
||||
})
|
||||
);
|
||||
} else {
|
||||
this.visitedViews.push(
|
||||
Object.assign({}, view, {
|
||||
title: view.meta?.title || 'no-name',
|
||||
})
|
||||
);
|
||||
}
|
||||
},
|
||||
addCachedView(view: any) {
|
||||
if (this.cachedViews.includes(view.name)) return;
|
||||
if (view.meta.keepAlive) {
|
||||
this.cachedViews.push(view.name);
|
||||
}
|
||||
},
|
||||
delVisitedView(view: any) {
|
||||
return new Promise((resolve) => {
|
||||
for (const [i, v] of this.visitedViews.entries()) {
|
||||
if (v.path === view.path) {
|
||||
this.visitedViews.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
resolve([...this.visitedViews]);
|
||||
});
|
||||
},
|
||||
delCachedView(view: any) {
|
||||
return new Promise((resolve) => {
|
||||
const index = this.cachedViews.indexOf(view.name);
|
||||
index > -1 && this.cachedViews.splice(index, 1);
|
||||
resolve([...this.cachedViews]);
|
||||
});
|
||||
},
|
||||
delOtherVisitedViews(view: any) {
|
||||
return new Promise((resolve) => {
|
||||
this.visitedViews = this.visitedViews.filter((v) => {
|
||||
return v.meta?.affix || v.path === view.path;
|
||||
});
|
||||
resolve([...this.visitedViews]);
|
||||
});
|
||||
},
|
||||
delOtherCachedViews(view: any) {
|
||||
return new Promise((resolve) => {
|
||||
const index = this.cachedViews.indexOf(view.name);
|
||||
if (index > -1) {
|
||||
this.cachedViews = this.cachedViews.slice(index, index + 1);
|
||||
} else {
|
||||
// if index = -1, there is no cached tags
|
||||
this.cachedViews = [];
|
||||
}
|
||||
resolve([...this.cachedViews]);
|
||||
});
|
||||
},
|
||||
export interface TagView extends Partial<RouteLocationNormalized> {
|
||||
title?: string;
|
||||
}
|
||||
|
||||
updateVisitedView(view: any) {
|
||||
for (let v of this.visitedViews) {
|
||||
// setup
|
||||
export const useTagsViewStore = defineStore('tagsView', () => {
|
||||
// state
|
||||
const visitedViews = ref<TagView[]>([]);
|
||||
const cachedViews = ref<string[]>([]);
|
||||
|
||||
// auctions
|
||||
function addVisitedView(view: TagView) {
|
||||
if (visitedViews.value.some(v => v.path === view.path)) return;
|
||||
if (view.meta && view.meta.affix) {
|
||||
visitedViews.value.unshift(
|
||||
Object.assign({}, view, {
|
||||
title: view.meta?.title || 'no-name'
|
||||
})
|
||||
);
|
||||
} else {
|
||||
visitedViews.value.push(
|
||||
Object.assign({}, view, {
|
||||
title: view.meta?.title || 'no-name'
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function addCachedView(view: TagView) {
|
||||
const viewName = view.name as string;
|
||||
if (cachedViews.value.includes(viewName)) return;
|
||||
if (view.meta?.keepAlive) {
|
||||
cachedViews.value.push(viewName);
|
||||
}
|
||||
}
|
||||
|
||||
function delVisitedView(view: TagView) {
|
||||
return new Promise(resolve => {
|
||||
for (const [i, v] of visitedViews.value.entries()) {
|
||||
if (v.path === view.path) {
|
||||
v = Object.assign(v, view);
|
||||
visitedViews.value.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
addView(view: any) {
|
||||
this.addVisitedView(view);
|
||||
this.addCachedView(view);
|
||||
},
|
||||
delView(view: any) {
|
||||
return new Promise((resolve) => {
|
||||
this.delVisitedView(view);
|
||||
this.delCachedView(view);
|
||||
resolve({
|
||||
visitedViews: [...this.visitedViews],
|
||||
cachedViews: [...this.cachedViews],
|
||||
});
|
||||
});
|
||||
},
|
||||
delOtherViews(view: any) {
|
||||
return new Promise((resolve) => {
|
||||
this.delOtherVisitedViews(view);
|
||||
this.delOtherCachedViews(view);
|
||||
resolve({
|
||||
visitedViews: [...this.visitedViews],
|
||||
cachedViews: [...this.cachedViews],
|
||||
});
|
||||
});
|
||||
},
|
||||
delLeftViews(view: any) {
|
||||
return new Promise((resolve) => {
|
||||
const currIndex = this.visitedViews.findIndex(
|
||||
(v) => v.path === view.path
|
||||
);
|
||||
if (currIndex === -1) {
|
||||
return;
|
||||
}
|
||||
this.visitedViews = this.visitedViews.filter((item, index) => {
|
||||
// affix:true 固定tag,例如“首页”
|
||||
if (index >= currIndex || (item.meta && item.meta.affix)) {
|
||||
return true;
|
||||
}
|
||||
resolve([...visitedViews.value]);
|
||||
});
|
||||
}
|
||||
|
||||
const cacheIndex = this.cachedViews.indexOf(item.name as string);
|
||||
if (cacheIndex > -1) {
|
||||
this.cachedViews.splice(cacheIndex, 1);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
resolve({
|
||||
visitedViews: [...this.visitedViews],
|
||||
});
|
||||
});
|
||||
},
|
||||
delRightViews(view: any) {
|
||||
return new Promise((resolve) => {
|
||||
const currIndex = this.visitedViews.findIndex(
|
||||
(v) => v.path === view.path
|
||||
);
|
||||
if (currIndex === -1) {
|
||||
return;
|
||||
}
|
||||
this.visitedViews = this.visitedViews.filter((item, index) => {
|
||||
// affix:true 固定tag,例如“首页”
|
||||
if (index <= currIndex || (item.meta && item.meta.affix)) {
|
||||
return true;
|
||||
}
|
||||
function delCachedView(view: TagView) {
|
||||
const viewName = view.name as string;
|
||||
return new Promise(resolve => {
|
||||
const index = cachedViews.value.indexOf(viewName);
|
||||
index > -1 && cachedViews.value.splice(index, 1);
|
||||
resolve([...cachedViews.value]);
|
||||
});
|
||||
}
|
||||
|
||||
const cacheIndex = this.cachedViews.indexOf(item.name as string);
|
||||
if (cacheIndex > -1) {
|
||||
this.cachedViews.splice(cacheIndex, 1);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
resolve({
|
||||
visitedViews: [...this.visitedViews],
|
||||
});
|
||||
function delOtherVisitedViews(view: TagView) {
|
||||
return new Promise(resolve => {
|
||||
visitedViews.value = visitedViews.value.filter(v => {
|
||||
return v.meta?.affix || v.path === view.path;
|
||||
});
|
||||
},
|
||||
delAllViews() {
|
||||
return new Promise((resolve) => {
|
||||
const affixTags = this.visitedViews.filter((tag) => tag.meta?.affix);
|
||||
this.visitedViews = affixTags;
|
||||
this.cachedViews = [];
|
||||
resolve({
|
||||
visitedViews: [...this.visitedViews],
|
||||
cachedViews: [...this.cachedViews],
|
||||
});
|
||||
resolve([...visitedViews.value]);
|
||||
});
|
||||
}
|
||||
|
||||
function delOtherCachedViews(view: TagView) {
|
||||
const viewName = view.name as string;
|
||||
return new Promise(resolve => {
|
||||
const index = cachedViews.value.indexOf(viewName);
|
||||
if (index > -1) {
|
||||
cachedViews.value = cachedViews.value.slice(index, index + 1);
|
||||
} else {
|
||||
// if index = -1, there is no cached tags
|
||||
cachedViews.value = [];
|
||||
}
|
||||
resolve([...cachedViews.value]);
|
||||
});
|
||||
}
|
||||
|
||||
function updateVisitedView(view: TagView) {
|
||||
for (let v of visitedViews.value) {
|
||||
if (v.path === view.path) {
|
||||
v = Object.assign(v, view);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addView(view: TagView) {
|
||||
addVisitedView(view);
|
||||
addCachedView(view);
|
||||
}
|
||||
|
||||
function delView(view: TagView) {
|
||||
return new Promise(resolve => {
|
||||
delVisitedView(view);
|
||||
delCachedView(view);
|
||||
resolve({
|
||||
visitedViews: [...visitedViews.value],
|
||||
cachedViews: [...cachedViews.value]
|
||||
});
|
||||
},
|
||||
delAllVisitedViews() {
|
||||
return new Promise((resolve) => {
|
||||
const affixTags = this.visitedViews.filter((tag) => tag.meta?.affix);
|
||||
this.visitedViews = affixTags;
|
||||
resolve([...this.visitedViews]);
|
||||
});
|
||||
}
|
||||
|
||||
function delOtherViews(view: TagView) {
|
||||
return new Promise(resolve => {
|
||||
delOtherVisitedViews(view);
|
||||
delOtherCachedViews(view);
|
||||
resolve({
|
||||
visitedViews: [...visitedViews.value],
|
||||
cachedViews: [...cachedViews.value]
|
||||
});
|
||||
},
|
||||
delAllCachedViews() {
|
||||
return new Promise((resolve) => {
|
||||
this.cachedViews = [];
|
||||
resolve([...this.cachedViews]);
|
||||
});
|
||||
}
|
||||
|
||||
function delLeftViews(view: TagView) {
|
||||
return new Promise(resolve => {
|
||||
const currIndex = visitedViews.value.findIndex(v => v.path === view.path);
|
||||
if (currIndex === -1) {
|
||||
return;
|
||||
}
|
||||
visitedViews.value = visitedViews.value.filter((item, index) => {
|
||||
// affix:true 固定tag,例如“首页”
|
||||
if (index >= currIndex || (item.meta && item.meta.affix)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const cacheIndex = cachedViews.value.indexOf(item.name as string);
|
||||
if (cacheIndex > -1) {
|
||||
cachedViews.value.splice(cacheIndex, 1);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
},
|
||||
},
|
||||
resolve({
|
||||
visitedViews: [...visitedViews.value]
|
||||
});
|
||||
});
|
||||
}
|
||||
function delRightViews(view: TagView) {
|
||||
return new Promise(resolve => {
|
||||
const currIndex = visitedViews.value.findIndex(v => v.path === view.path);
|
||||
if (currIndex === -1) {
|
||||
return;
|
||||
}
|
||||
visitedViews.value = visitedViews.value.filter((item, index) => {
|
||||
// affix:true 固定tag,例如“首页”
|
||||
if (index <= currIndex || (item.meta && item.meta.affix)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const cacheIndex = cachedViews.value.indexOf(item.name as string);
|
||||
if (cacheIndex > -1) {
|
||||
cachedViews.value.splice(cacheIndex, 1);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
resolve({
|
||||
visitedViews: [...visitedViews.value]
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function delAllViews() {
|
||||
return new Promise(resolve => {
|
||||
const affixTags = visitedViews.value.filter(tag => tag.meta?.affix);
|
||||
visitedViews.value = affixTags;
|
||||
cachedViews.value = [];
|
||||
resolve({
|
||||
visitedViews: [...visitedViews.value],
|
||||
cachedViews: [...cachedViews.value]
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function delAllVisitedViews() {
|
||||
return new Promise(resolve => {
|
||||
const affixTags = visitedViews.value.filter(tag => tag.meta?.affix);
|
||||
visitedViews.value = affixTags;
|
||||
resolve([...visitedViews.value]);
|
||||
});
|
||||
}
|
||||
|
||||
function delAllCachedViews() {
|
||||
return new Promise(resolve => {
|
||||
cachedViews.value = [];
|
||||
resolve([...cachedViews.value]);
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
visitedViews,
|
||||
cachedViews,
|
||||
addVisitedView,
|
||||
addCachedView,
|
||||
delVisitedView,
|
||||
delCachedView,
|
||||
delOtherVisitedViews,
|
||||
delOtherCachedViews,
|
||||
updateVisitedView,
|
||||
addView,
|
||||
delView,
|
||||
delOtherViews,
|
||||
delLeftViews,
|
||||
delRightViews,
|
||||
delAllViews,
|
||||
delAllVisitedViews,
|
||||
delAllCachedViews
|
||||
};
|
||||
});
|
||||
|
||||
export default useTagsViewStore;
|
||||
|
||||
@@ -1,103 +1,101 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { UserState } from './types';
|
||||
|
||||
import { localStorage } from '@/utils/storage';
|
||||
import { getToken, setToken, removeToken } from '@/utils/auth';
|
||||
import { loginApi, logoutApi } from '@/api/auth';
|
||||
import { getUserInfo } from '@/api/user';
|
||||
import { resetRouter } from '@/router';
|
||||
import { LoginForm } from '@/api/auth/types';
|
||||
import { store } from '@/store';
|
||||
import { LoginData } from '@/api/auth/types';
|
||||
import { ref } from 'vue';
|
||||
import { UserInfo } from '@/api/user/types';
|
||||
|
||||
const useUserStore = defineStore({
|
||||
id: 'user',
|
||||
state: (): UserState => ({
|
||||
token: localStorage.get('token') || '',
|
||||
nickname: '',
|
||||
avatar: '',
|
||||
roles: [],
|
||||
perms: []
|
||||
}),
|
||||
actions: {
|
||||
async RESET_STATE() {
|
||||
this.$reset();
|
||||
},
|
||||
/**
|
||||
* 登录
|
||||
*/
|
||||
login(data: LoginForm) {
|
||||
const { username, password } = data;
|
||||
return new Promise((resolve, reject) => {
|
||||
loginApi({
|
||||
grant_type: 'password',
|
||||
username: username.trim(),
|
||||
password: password
|
||||
export const useUserStore = defineStore('user', () => {
|
||||
// state
|
||||
const token = ref<string>(getToken() || '');
|
||||
const nickname = ref<string>('');
|
||||
const avatar = ref<string>('');
|
||||
const roles = ref<Array<string>>([]); // 用户角色编码集合 → 判断路由权限
|
||||
const perms = ref<Array<string>>([]); // 用户权限编码集合 → 判断按钮权限
|
||||
|
||||
// auctions
|
||||
|
||||
// 登录
|
||||
function login(loginData: LoginData) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
loginApi(loginData)
|
||||
.then(response => {
|
||||
const { accessToken } = response.data;
|
||||
token.value = accessToken;
|
||||
setToken(accessToken);
|
||||
resolve();
|
||||
})
|
||||
.then(response => {
|
||||
console.log('response.data', response.data);
|
||||
const accessToken = response.data;
|
||||
localStorage.set('token', accessToken);
|
||||
this.token = accessToken;
|
||||
resolve(accessToken);
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取用户信息(昵称、头像、角色集合、权限集合)
|
||||
*/
|
||||
getUserInfo() {
|
||||
return new Promise((resolve, reject) => {
|
||||
getUserInfo()
|
||||
.then(({ data }) => {
|
||||
if (!data) {
|
||||
return reject('Verification failed, please Login again.');
|
||||
}
|
||||
const { nickname, avatar, roles, perms } = data;
|
||||
if (!roles || roles.length <= 0) {
|
||||
reject('getUserInfo: roles must be a non-null array!');
|
||||
}
|
||||
this.nickname = nickname;
|
||||
this.avatar = avatar;
|
||||
this.roles = roles;
|
||||
this.perms = perms;
|
||||
resolve(data);
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 注销
|
||||
*/
|
||||
logout() {
|
||||
return new Promise((resolve, reject) => {
|
||||
logoutApi()
|
||||
.then(() => {
|
||||
localStorage.remove('token');
|
||||
this.RESET_STATE();
|
||||
resetRouter();
|
||||
resolve(null);
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 清除 Token
|
||||
*/
|
||||
resetToken() {
|
||||
return new Promise(resolve => {
|
||||
localStorage.remove('token');
|
||||
this.RESET_STATE();
|
||||
resolve(null);
|
||||
});
|
||||
}
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 获取信息(用户昵称、头像、角色集合、权限集合)
|
||||
function getInfo() {
|
||||
return new Promise<UserInfo>((resolve, reject) => {
|
||||
getUserInfo()
|
||||
.then(({ data }) => {
|
||||
if (!data) {
|
||||
return reject('Verification failed, please Login again.');
|
||||
}
|
||||
if (!data.roles || data.roles.length <= 0) {
|
||||
reject('getUserInfo: roles must be a non-null array!');
|
||||
}
|
||||
nickname.value = data.nickname;
|
||||
avatar.value = data.avatar;
|
||||
roles.value = data.roles;
|
||||
perms.value = data.perms;
|
||||
resolve(data);
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 注销
|
||||
function logout() {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
logoutApi()
|
||||
.then(() => {
|
||||
resetRouter();
|
||||
resetToken();
|
||||
resolve();
|
||||
})
|
||||
.catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 重置
|
||||
function resetToken() {
|
||||
removeToken();
|
||||
token.value = '';
|
||||
nickname.value = '';
|
||||
avatar.value = '';
|
||||
roles.value = [];
|
||||
perms.value = [];
|
||||
}
|
||||
return {
|
||||
token,
|
||||
nickname,
|
||||
avatar,
|
||||
roles,
|
||||
perms,
|
||||
login,
|
||||
getInfo,
|
||||
logout,
|
||||
resetToken
|
||||
};
|
||||
});
|
||||
|
||||
export default useUserStore;
|
||||
// 非setup
|
||||
export function useUserStoreHook() {
|
||||
return useUserStore(store);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user