如何用ts搭建一个vue3通用项目底座 | 第五篇:项目初始化配置

前言

完善一下项目初始化配置,分为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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值