1.store/index.ts
import { createPinia } from 'pinia';
import useAppStore from './modules/app';
import useUserStore from './modules/user';
import useTabBarStore from './modules/tab-bar';
const pinia = createPinia();
export { useAppStore, useUserStore, useTabBarStore };
export default pinia;
2.modules
2.1modules/user/index.ts
import { defineStore } from 'pinia';
import { getUserInfo } from '@/api/user';
import { clearToken, setToken } from '@/utils/auth';
import { removeRouteListener } from '@/utils/route-listener';
import { UserState } from '@/store/modules/user/types';
import {
CaptchaRes,
getCaptcha,
login as userLogin,
LoginData,
logout as userLogout,
} from '@/api/auth';
import useAppStore from '../app';
const useUserStore = defineStore('user', {
state: (): UserState => ({
username: undefined,
nickname: undefined,
avatar: undefined,
is_superuser: false,
is_staff: false,
roles: '',
}),
getters: {
userInfo(state: UserState): UserState {
return { ...state };
},
},
actions: {
setInfo(partial: Partial<UserState>) {
this.$patch(partial);
},
resetInfo() {
this.$reset();
},
async info() {
const res = await getUserInfo();
this.setInfo(res);
},
async captcha() {
const res: CaptchaRes = await getCaptcha();
return res.image;
},
async login(loginForm: LoginData) {
try {
const res = await userLogin(loginForm);
setToken(res.access_token);
} catch (err) {
clearToken();
throw err;
}
},
logoutCallBack() {
const appStore = useAppStore();
this.resetInfo();
clearToken();
removeRouteListener();
appStore.clearServerMenu();
},
async logout() {
try {
await userLogout();
} finally {
this.logoutCallBack();
}
},
},
});
export default useUserStore;
2.2modules/user/type
export interface UserState {
username?: string;
nickname?: string;
avatar?: string;
is_superuser: boolean;
is_staff: boolean;
roles: string;
}
3.main.ts
import { createApp } from 'vue';
import ArcoVue from '@arco-design/web-vue';
import ArcoVueIcon from '@arco-design/web-vue/es/icon';
import globalComponents from '@/components';
import router from './router';
import store from './store';
import i18n from './locale';
import directive from './directive';
import App from './App.vue';
import '@/assets/style/global.less';
import '@/api/interceptor';
const app = createApp(App);
app.config.warnHandler = () => null;
app.use(ArcoVue, {});
app.use(ArcoVueIcon);
app.use(router);
app.use(store);
app.use(i18n);
app.use(globalComponents);
app.use(directive);
app.mount('#app');