跳转到主要内容

UI架构说明

1. 系统架构概述

Wimoor UI3 是一个基于 Vue 3 + Element Plus 构建的企业级前端应用框架,采用现代化的技术栈和架构设计理念。系统采用了组件化、模块化和分层架构,具有良好的可扩展性、可维护性和性能。

1.1 技术栈

技术 版本 用途
Vue 3.x 前端框架
Element Plus 2.x UI组件库
Vue Router 4.x 路由管理
Vuex 4.x 状态管理
Axios 0.27.x HTTP客户端
Vite 3.x 构建工具
SVG - 图标系统

1.2 系统分层

  • 表示层:Vue 组件、视图、布局
  • 控制层:路由、导航守卫
  • 业务逻辑层:Vuex Store、API服务
  • 数据访问层:Axios请求封装
  • 工具层:全局工具函数、指令

2. 核心架构组件

2.1 应用入口 (main.js)

应用入口文件负责初始化 Vue 应用,注册全局组件、指令、过滤器和方法。

核心功能

  • Vue 应用创建与挂载
  • Element Plus 注册与配置
  • 路由与状态管理注册
  • 全局组件注册 (SvgIcon, DictTag, Pagination, GlobalTable等)
  • 自定义指令注册 (v-hasPerm, v-hasPermi, v-dataType)
  • 全局方法挂载 (parseTime, download, useDict等)

关键代码

// 创建Vue应用
const app = createApp(App);

// 注册核心依赖
app.use(store).use(router).use(ElementPlus).use(print).use(plugins);

// 注册全局组件
app.component('GlobalTable', GlobalTable);
app.component('Pagination', Pagination);

// 注册自定义指令
app.use(hasPerm).use(hasPermi).use(dataType);

// 挂载应用
app.mount('#app');

2.2 路由系统

路由系统采用 Vue Router 4,支持静态路由和动态路由结合的方式。

2.2.1 路由配置

路由配置分为静态路由和动态路由两部分:

  • 静态路由:在前端代码中定义的固定路由,如登录页、首页等
  • 动态路由:从后端API获取的业务路由,根据用户权限动态加载

路由模块划分

  • sysRouter.js:系统管理相关路由
  • erp.js:ERP模块路由
  • amazon.js:亚马逊模块路由
  • finance.js:财务模块路由

2.2.2 路由守卫

使用 beforeEach 导航守卫实现权限控制和动态路由加载:

router.beforeEach(async (to, from, next) => {
  if (whitePath.includes(to.path)) {
    // 白名单路由直接放行
    next();
  } else {
    if (store.state.routerStore.router.length === 0) {
      // 动态加载路由
      await axios.get('/api/admin/api/v1/menus/route').then(res => {
        store.dispatch("routerStore/setRouter", res.data.data);
        addRoute(router, res.data.data);
      });
    }
    next();
  }
});

2.2.3 动态路由加载

通过 addRoute 函数实现动态路由的递归加载:

function addRoute(router, data) {
  data.forEach(v => {
    let item = {
      path: v.path,
      name: v.name,
      component: modules[`../views/${v.component}.vue`],
      meta: v.meta || { keepAlive: true }
    };
    // 过滤不需要缓存的页面
    if (['/sys/notepad', '/fin/voucher/create'].includes(item.path)) {
      item.meta.keepAlive = false;
    }
    router.addRoute('index', item);
    // 递归加载子路由
    if (v.children) {
      addRoute(router, v.children);
    }
  });
}

2.3 Layout 结构

Layout 采用了经典的三栏布局结构,使用 Element Plus 的 el-container 组件实现。

2.3.1 布局组件结构

<el-container>
  <el-aside>           <!-- 左侧菜单 -->
    <AsideMenu />
  </el-aside>
  <el-container>
    <el-header>        <!-- 顶部导航 -->
      <HeaderTab />
      <HeaderAvatar />
    </el-header>
    <el-main>          <!-- 主内容区 -->
      <router-view>
        <!-- 页面内容 -->
      </router-view>
    </el-main>
  </el-container>
</el-container>

2.3.2 布局组件说明

  • AsideMenu:左侧菜单组件,负责展示系统菜单和主题切换
  • HeaderTab:顶部标签页组件,管理当前打开的页面标签
  • HeaderAvatar:用户头像组件,提供用户信息和系统设置入口

2.3.3 组件缓存机制

使用 Vue 的 keep-alive 组件实现页面缓存,提高用户体验:

<keep-alive ref="keepAlive" :exclude="excludes">
  <component :is="wrap($route.query.title, Component)" v-if="$route.meta.keepAlive" :key="$route.query.title" />
</keep-alive>
<component :is="wrap($route.query.title, Component)" v-if="!$route.meta.keepAlive" :key="$route.query.title" />

动态缓存控制

  • 通过 meta.keepAlive 控制页面是否需要缓存
  • 使用 excludes 数组动态移除不需要缓存的组件
  • 提供 clearCache 方法实现页面刷新

2.4 状态管理

采用 Vuex 4 实现状态管理,按功能模块划分为多个子模块。

2.4.1 Store 模块划分

  • routerStore:路由相关状态管理
  • permissionStore:权限相关状态管理
  • jessionStore:会话相关状态管理
  • dateStore:日期相关状态管理
  • finance:财务模块状态管理
  • dict:字典数据状态管理

2.4.2 核心状态管理

routerStore

  • 管理动态路由数据
  • 提供路由设置和获取方法

permissionStore

  • 管理用户权限列表
  • 提供权限判断方法

2.5 权限控制

系统实现了基于指令的权限控制机制,通过 v-hasPermv-hasPermi 指令控制元素的显示。

2.5.1 权限指令

// v-hasPerm 指令:判断用户是否拥有特定权限
export const hasPerm = {
  install: (app) => {
    app.directive('hasPerm', {
      mounted(el, binding) {
        const permissions = store.state.permissionStore.permission;
        const value = binding.value;
        const hasPermission = permissions.has(value);
        if (!hasPermission) {
          el.parentNode.removeChild(el);
        }
      }
    });
  }
};

// v-hasPermi 指令:判断用户是否拥有任一指定权限
export const hasPermi = {
  install: (app) => {
    app.directive('hasPermi', {
      mounted(el, binding) {
        const permissions = Array.from(store.state.permissionStore.permission);
        const permissionFlag = binding.value;
        const hasPermissions = permissions.some(permission => {
          return "*:*:*" === permission || permissionFlag.includes(permission);
        });
        if (!hasPermissions) {
          el.parentNode.removeChild(el);
        }
      }
    });
  }
};

3. 公共组件与工具

3.1 全局组件

系统提供了一系列可复用的全局组件:

3.1.1 GlobalTable 组件

基于 Element Plus Table 封装的全局表格组件,提供了丰富的功能和配置选项。

核心功能

  • 数据加载与分页
  • 排序与筛选
  • 选择与点击事件
  • 行展开与树形结构
  • 自定义列与表头
  • 空数据提示

使用示例

<GlobalTable
  :table-data="tableData"
  :loading="loading"
  @row-click="handleRowClick"
  @selection-change="handleSelectionChange"
>
  <el-table-column prop="name" label="名称" />
  <el-table-column prop="status" label="状态" />
</GlobalTable>

3.1.2 Pagination 组件

分页组件,与 GlobalTable 配合使用。

3.1.3 SvgIcon 组件

SVG 图标组件,支持动态加载和自定义样式。

3.1.4 DictTag 组件

字典标签组件,用于显示字典值对应的标签。

3.2 全局工具函数

系统提供了丰富的全局工具函数,挂载在 Vue 实例上:

  • parseTime:日期时间格式化
  • resetForm:表单重置
  • addDateRange:日期范围处理
  • handleTree:树形数据处理
  • selectDictLabel:字典标签选择
  • download:文件下载

3.3 自定义指令

  • v-hasPerm:单个权限控制
  • v-hasPermi:多个权限控制
  • v-dataType:数据类型验证

4. 通信机制

4.1 组件通信

系统使用多种组件通信方式:

  • Props/Emits:父子组件通信
  • Provide/Inject:跨组件层级通信
  • Event Bus:基于 mitt 的事件总线
  • Vuex:全局状态共享

4.2 API 通信

使用 Axios 作为 HTTP 客户端,实现与后端 API 的通信。

API 请求流程

  1. 前端组件发起请求
  2. API 服务层处理请求参数
  3. Axios 拦截器处理请求头和响应
  4. 后端处理请求并返回数据
  5. 前端接收响应并处理

5. 性能优化

5.1 组件缓存

使用 keep-alive 缓存常用页面组件,减少重复渲染。

5.2 路由懒加载

采用动态导入方式实现路由懒加载:

component: () => import("@/views/dashboard/index.vue")

5.3 图片优化

使用 SVG 图标代替 PNG/JPG 图标,减少网络请求。

5.4 代码分割

利用 Vite 的代码分割功能,按需加载模块。

6. 开发规范

6.1 目录结构

src/
├── api/           # API服务
├── assets/        # 静态资源
├── components/    # 公共组件
├── directive/     # 自定义指令
├── filters/       # 过滤器
├── layout/        # 布局组件
├── router/        # 路由配置
├── store/         # 状态管理
├── styles/        # 样式文件
├── utils/         # 工具函数
├── views/         # 页面视图
├── App.vue        # 根组件
└── main.js        # 入口文件

6.2 命名规范

  • 组件名:PascalCase,如 GlobalTable
  • 文件名:kebab-case,如 global-table.vue
  • 变量名:camelCase
  • 常量名:UPPER_SNAKE_CASE

6.3 代码风格

  • 使用 Vue 3 Composition API
  • 优先使用模板语法
  • 合理使用 TypeScript 类型
  • 保持代码简洁和可读性

7. 部署与维护

7.1 构建流程

# 安装依赖
npm install

# 开发环境
npm run dev

# 生产构建
npm run build

7.2 环境配置

  • 开发环境:配置 .env.development
  • 测试环境:配置 .env.test
  • 生产环境:配置 .env.production

7.3 常见问题

  • 路由加载失败:检查后端API返回的路由格式是否正确
  • 权限控制不生效:检查用户权限列表是否正确获取
  • 组件缓存问题:检查 meta.keepAlive 配置是否正确

8. 总结

Wimoor UI3 是一个架构清晰、功能完善的企业级前端应用框架,采用了现代化的技术栈和设计理念。系统具有良好的可扩展性、可维护性和性能,能够满足企业不断发展的业务需求。

通过本架构说明文档,希望能帮助开发人员更好地理解系统架构和设计思想,提高开发效率和代码质量。


文档版本:1.0 更新日期:2023-07-01 编写人员:Wimoor UI3 开发团队