Skip to content

前端环境与结构

说明

前端基于 Vue3 + ElementPlus 构建,使用 pnpm 作为包管理工具,Vite 作为构建工具,TypeScript 作为开发语言。

技术栈

技术版本说明
Vue3.x渐进式 JavaScript 框架,组合式 API
ElementPlus2.xVue3 组件库
Vite3.x下一代前端构建工具
Pinia2.x状态管理(Vuex 替代方案)
Vue Router4.x路由管理
Axios1.xHTTP 请求库
TypeScript5.x类型安全的 JavaScript 超集
Tailwind CSS3.x原子化 CSS 框架
SCSS-CSS 预处理器

目录结构

ui/
├── src/
│ ├── api/          # API 接口定义
│ │ ├── common/     # 公共接口(login、menu、user)
│ │ └── system/     # 系统模块接口(position、user、role 等)
│ ├── assets/       # 静态资源(图片、字体等)
│ ├── components/   # 公共组件(Table、Form、Modal 等)
│ ├── directives/   # 自定义指令(v-perm 权限指令)
│ ├── hooks/        # 组合式函数
│ │ ├── event/      # 事件相关(useWindowSizeFn、useBreakpoint)
│ │ ├── setting/    # 配置相关(useProjectSetting、useDesignSetting)
│ │ └── web/        # Web 相关(usePermission、useECharts)
│ ├── layout/       # 布局组件
│ ├── router/       # 路由配置(generator-routers、router-guards)
│ ├── store/        # Pinia 状态管理
│ │ └── modules/    # Store 模块(user、asyncRoute、projectSetting 等)
│ ├── styles/       # 全局样式(SCSS 变量、Tailwind)
│ ├── utils/        # 工具函数(http、auth、Storage、dateUtil)
│ │ └── http/axios/ # Axios 封装(VAxios 类、拦截器、取消请求)
│ └── views/        # 页面视图
│ └── system/       # 系统管理页面(position、user、role 等)
├── build/          # 构建配置(vite 插件、常量、工具函数)
├── public/         # 公共静态资源
├── vite.config.ts  # Vite 配置
├── tsconfig.json   # TypeScript 配置
└── package.json    # 依赖配置

启动开发

bash
# 安装依赖
pnpm install

# 启动开发服务器(默认端口 8001)
pnpm dev

# 构建生产版本
pnpm build

Vite 配置

vite.config.ts 是 Vite 的核心配置文件,实际配置如下:

typescript
import type { UserConfig, ConfigEnv } from 'vite';
import { loadEnv } from 'vite';
import { resolve } from 'path';
import { wrapperEnv } from './build/utils';
import { createVitePlugins } from './build/vite/plugin';
import { OUTPUT_DIR } from './build/constant';
import { createProxy } from './build/vite/proxy';

export default ({ command, mode }: ConfigEnv): UserConfig => {
    const root = process.cwd();
    const env = loadEnv(mode, root);
    const viteEnv = wrapperEnv(env);
    const { VITE_PUBLIC_PATH, VITE_PORT, VITE_GLOB_PROD_MOCK } = viteEnv;

    let VITE_PROXY: any = viteEnv.VITE_PROXY;
    // VITE_PROXY 容错处理
    if (!VITE_PROXY) {
        VITE_PROXY = '[[]]';
    }
    try {
        if (typeof VITE_PROXY === 'string') {
            VITE_PROXY = JSON.parse(VITE_PROXY);
        }
    } catch (e) {
        VITE_PROXY = [[]];
    }

    const isBuild = command === 'build';

    return {
        base: VITE_PUBLIC_PATH,
        resolve: {
            alias: [
                { find: '@', replacement: pathResolve('src') + '/' },
            ],
            dedupe: ['vue'],
        },
        plugins: createVitePlugins(viteEnv, isBuild, prodMock),
        css: {
            preprocessorOptions: {
                scss: {
                    additionalData: `@import "src/styles/var.scss";`,
                },
            },
        },
        server: {
            host: true,
            port: VITE_PORT,
            proxy: createProxy(VITE_PROXY),
        },
        build: {
            target: 'es2015',
            outDir: OUTPUT_DIR,
            reportCompressedSize: false,
            chunkSizeWarningLimit: 2000,
        },
    };
};

关键配置说明:

  • @ 别名指向 src/ 目录,代码中可用 @/api/system/position 引入模块
  • SCSS 全局变量通过 additionalData 注入,无需每个文件手动 @import
  • 代理配置通过 VITE_PROXY 环境变量传入,由 createProxy() 工具函数解析
  • 构建产物输出到 OUTPUT_DIR(默认 dist/

应用入口

src/main.ts 是应用入口,负责初始化所有基础设施:

typescript
import './styles/tailwindbase.css';
import 'element-plus/dist/index.css';
import './styles/index.scss';
import * as ElementPlusIconsVue from '@element-plus/icons-vue';
import { createApp } from 'vue';
import App from './App.vue';
import router, { setupRouter } from './router';
import { setupStore } from '@/store';
import { setupElement, setupDirectives, setupCustomComponents } from '@/plugins';

async function bootstrap() {
    const app = createApp(App);

    // 注册所有 ElementPlus 图标
    for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
        app.component(key, component);
    }

    setupElement(app);              // 全局引入 ElementPlus 组件
    setupCustomComponents(app);     // 注册自定义组件
    setupDirectives(app);           // 注册自定义指令(v-perm 等)
    setupStore(app);                // 挂载 Pinia 状态管理
    await setupRouter(app);         // 挂载路由
    await router.isReady();         // 路由准备就绪

    app.mount('#app', true);
}

void bootstrap();

初始化顺序:样式加载 -> ElementPlus -> 自定义组件 -> 自定义指令 -> Pinia Store -> Router -> 挂载。

核心目录说明

api/

API 接口定义目录,按模块组织文件。公共接口在 api/common/(login、menu、user),业务接口在 api/system/(position、user、role、dept、level、menu、dictionary 等)。每个文件使用 http.request() 发起请求。

components/

公共组件目录,基于 ElementPlus 二次封装,包含 Table(BasicTable 表格)、Form(BasicForm 表单)、Modal(BasicModal 弹窗)、UploadEditorCropperSelect 等。

directives/

自定义指令目录,核心是 permission.ts 中的 v-permv-perms 指令,用于按钮级别的权限控制。

hooks/

组合式函数目录,包括 usePermission(权限检查)、useTime(实时时钟)、useAsync(异步 loading)、useProjectSetting(项目配置)、useDesignSetting(设计配置)等。

store/

Pinia 状态管理目录,核心模块:

  • user:用户登录状态、Token、用户信息、权限列表
  • asyncRoute:动态路由生成、菜单管理、组件缓存
  • projectSetting:项目配置(权限模式、水印等)
  • designSetting:主题色、深色模式
  • lockscreen:锁屏状态
  • tabsView:标签页管理

utils/

工具函数目录:

  • http/axios/:Axios 封装(VAxios 类、请求/响应拦截器、取消重复请求、状态码处理)
  • auth.ts:认证工具(token 管理、树结构操作、文件下载)
  • Storage.ts:本地存储封装(支持过期时间、cookie)
  • dateUtil.ts:日期格式化(基于 dayjs)

总结

前端项目基于 Vue3 + ElementPlus + Vite + TypeScript + Pinia 构建,使用 pnpm 管理依赖,Tailwind CSS + SCSS 提供样式能力。通过 main.tsbootstrap() 函数按顺序初始化所有基础设施,目录结构按功能分层组织,便于维护和扩展。

小蚂蚁云团队 · 提供技术支持