前言
完善一下项目初始化配置,分为store配置、初始化内部系统配置、注册全局组件、配置路由、路由守卫、注册全局指令、配置全局错误处理这些内容。
1、配置 store
在src/stores文件夹下新建一个index.ts,顺便删除原有的counter.ts
// src/stores/index.ts
import type {
App } from 'vue';
import {
createPinia } from 'pinia';
const store = createPinia();
export function setupStore(app: App<Element>) {
app.use(store);
}
export {
store };
更改一下main.ts里有关store的部分
// main.ts
import './style/tailwind.scss';
import './assets/main.css';
import {
createApp } from 'vue';
import App from './App.vue';
import router from './router';
import {
setupStore } from '/@/stores';
async function bootstrap() {
const app = createApp(App);
// 配置 store
setupStore(app);
app.use(router);
app.mount('#app');
}
bootstrap();
注意这里的bootstrap函数,后面几步的setupXXX都会在这里调用
接着在stores文件夹下新建modules文件夹,里面新建app.ts文件用来存放项目配置
// app.ts
import {
defineStore } from 'pinia';
import {
store } from '/@/stores';
import {
ProjectConfig } from '/#/config';
import {
PROJ_CFG_KEY } from '/@/enums/cacheEnum';
import {
Persistent } from '/@/utils/cache/persistent';
import {
deepMerge } from '/@/utils';
// app基本配置
interface AppState {
// 页面加载状态
pageLoading: boolean;
// 项目配置
projectConfig: ProjectConfig | null;
}
export const useAppStore = defineStore({
id: 'app',
state: (): AppState => ({
pageLoading: false,
projectConfig: Persistent.getLocal(PROJ_CFG_KEY),
}),
getters: {
getPageLoading(state): boolean {
return state.pageLoading;
},
getProjectConfig(state): ProjectConfig {
return state.projectConfig || ({
} as ProjectConfig);
},
},
actions: {
setPageLoading(loading: boolean): void {
this.pageLoading = loading;
},
setProjectConfig(config: DeepPartial<ProjectConfig>): void {
this.projectConfig = deepMerge(this.projectConfig || {
}, config) as ProjectConfig;
Persistent.setLocal(PROJ_CFG_KEY, this.projectConfig);
},
},
});
// 需要在设置之外使用
export function useAppStoreWithOut() {
return useAppStore(store);
}
这里面用到的utils函数在上一篇utils配置中有提到
使用场景
// demo
import {
useAppStoreWithOut } from '/@/stores/modules/app';
const appStore = useAppStoreWithOut();
appStore.setPageLoading(false);
2、初始化内部系统配置
新建/@/logics/initAppConfig.ts文件
// initAppConfig.ts
/**
* 应用程序配置
*/
import type {
ProjectConfig } from '/#/config';
import {
PROJ_CFG_KEY } from '/@/enums/cacheEnum';
import projectSetting from '/@/settings/projectSetting';
import {
useAppStore } from '/@/stores/modules/app';
import {
getCommonStoragePrefix, getStorageShortName } from '/@/utils/env';
import {
Persistent } from '/@/utils/cache/persistent';
import {
deepMerge } from '/@/utils';
// 初始项目配置
export function initAppConfigStore() {
const appStore = useAppStore();
let projCfg: ProjectConfig = Persistent.getLocal(PROJ_CFG_KEY) as ProjectConfig;
projCfg = deepMerge(projectSetting, projCfg || {
});
appStore.setProjectConfig(projCfg);
setTimeout(() => {
clearObsoleteStorage();
}, 16);
}
/**
* 随着版本的不断迭代,localStorage中存储的缓存密钥将越来越多
* 此方法用于删除无用的密钥
*/
export function clearObsoleteStorage() {
const commonPrefix = getCommonStoragePrefix();
const shortPrefix = getStorageShortName();
[localStorage, sessionStorage].forEach((item: Storage) => {
Object.keys(item).forEach((key) => {
if (key && key.startsWith(commonPrefix) && !key.startsWith(shortPrefix)) {
item.removeItem(key);
}
});
});
}
/@/settings/projectSetting这个文件需要新建一下。
// projectSetting.ts
import type {
ProjectConfig } from '/#/config';
import {
SessionTimeoutProcessingEnum } from '/@/enums/appEnum';
// ! 更改后需要清除浏览器缓存
const setting: ProjectConfig = {
// 会话超时处理
sessionTimeoutProcessing: SessionTimeoutProcessingEnum.ROUTE_JUMP,
// 使用错误处理程序插件
useErrorHandle: false,
// 切换接口时是否删除未关闭的消息并通知
closeMessageOnSwitch: true,
// 切换路由时是否取消已发送但未响应的http请求
// 如果启用了它,我想覆盖单个接口。可以在单独的界面中设置
removeAllHttpPending: false,
};
export default setting;
/@/enums/appEnum这个文件需要新建一下。
// appEnum.ts
// 会话超时处理
export enum SessionTimeoutProcessingEnum {
ROUTE_JUMP,
PAGE_COVERAGE,
}
更改一下main.ts文件。
// main.ts
import './style/tailwind.scss';
import './assets/main.css';
import {
createApp } from 'vue';
import App from './App.vue';
import router from './router';
import {
setupStore } from '/@/stores';
import {
initAppConfigStore } from './logics/initAppConfig';
async function bootstrap() {
const app = createApp(App);
// 配置 store
setupStore(app);
// 初始化内部系统配置
initAppConfigStore();
app.use(router);
app.mount('#app');
}
bootstrap();
3、注册全局组件
这部分我采用的全局引入的方式,如果需要按需引入,按照组件库官网提供的方式修改即可,也可以用我自己常用的方法。
新建/@/components/registerGlobComp.ts文件。
// registerGlobComp.ts
import type {
App } from 'vue';
import VXETable from 'vxe-table';
import ElementPlus from 'element-plus';
import 'xe-utils';
export function registerGlobComp(app: App) {
app.use(VXETable).use(ElementPlus);
}
安装组件库
// package.json
"vxe-table": "^4.3.12",
"element-plus": "^2.3.4",
"xe-utils": "^3.5.7",
如果需要按需引入,registerGlobComp.ts文件可以这样写。
// registerGlobComp.ts
import type {
App } from 'vue';
import VXETable from 'vxe-table';
import {
ElButton, ElAlert } from 'element-plus';
import 'xe-utils';
export function registerGlobComp(app: App) {
app.use(VXETable).use(ElButton).use(ElAlert);
}
修改一下main.ts
// main.ts
import './style/tailwind.scss';
import './assets/main.css';
import {
createApp } from 'vue';
import App from './App.vue';
import router from './router';
import {
setupStore } from '/@/stores';
import {
initAppConfigStore } from './logics/initAppConfig';
import {
registerGlobComp } from './components/registerGlobComp';
async function bootstrap() {
const app = createApp(App);
// 配置 store
setupStore(app);
// 初始化内部系统配置
initAppConfigStore();
// 注册全局组件
registerGlobComp(app);
app.use(router);
app.mount('#app');
}
bootstrap();
4、配置路由
把原有的文件删掉,重新按照下面的结构新建一个。
直接上代码。
// /@/router/routes/modules/about.ts
// 路由示例
const abouteDemo = {
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (About.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import('/@/views/AboutView.vue'),
};
export default abouteDemo;
// /@/router/routes/modules/home.ts
import HomeView from '/@/views/HomeView.vue';
// 路由示例
const homeDemo = {
path: '/home',
name: 'home',
// route level code-splitting
// this generates a separate chunk (About.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import('/@/views/HomeView.vue'),
};
export default homeDemo;
// /@/router/routes/index.ts
import {
AppRouteModule, AppRouteRecordRaw } from '/@/router/types';
import {
PageEnum } from '/@/enums/pageEnum';
const modules = import.meta.glob('./modules/**/*.ts', {
import: 'default', eager: true });
const routeModuleList: AppRouteModule[] = [];
Object.keys(modules)