# PIGX 前端技术文档汇总
> **更新日期**: 2025-10-23
> **适配版本**: 5.0 以上单体和微服务版本
---
## 目录
- [一、环境配置](#一环境配置)
- [1.1 ENV 环境配置](#11-env环境配置)
- [1.2 前端配置项说明](#12-前端配置项说明)
- [二、项目结构](#二项目结构)
- [2.1 目录结构](#21-目录结构)
- [三、核心功能](#三核心功能)
- [3.1 国际化配置](#31-国际化配置)
- [3.2 字体图标配置](#32-字体图标配置)
- [3.3 权限管理](#33-权限管理)
- [3.4 路由管理](#34-路由管理)
- [3.5 标签页管理](#35-标签页管理)
- [3.6 数据状态管理](#36-数据状态管理)
- [四、工具函数](#四工具函数)
- [4.1 字典工具使用](#41-字典工具使用)
- [4.2 参数工具使用](#42-参数工具使用)
- [4.3 通用工具函数](#43-通用工具函数)
- [五、组件使用](#五组件使用)
- [5.1 表格组件](#51-表格组件)
- [5.2 表格分页组件](#52-表格分页组件)
- [5.3 表格工具栏组件](#53-表格工具栏组件)
- [5.4 上传组件](#54-上传组件)
- [5.5 富文本组件](#55-富文本组件)
- [5.6 代码编辑组件](#56-代码编辑组件)
- [5.7 图表功能](#57-图表功能)
- [5.8 左侧查询树](#58-左侧查询树)
- [5.9 组织架构组件](#59-组织架构组件)
- [5.10 标签列表组件](#510-标签列表组件)
- [5.11 悬浮输入组件](#511-悬浮输入组件)
- [5.12 文字提示组件](#512-文字提示组件)
- [5.13 省市区街四级联动组件](#513-省市区街四级联动组件)
- [5.14 表单校验](#514-表单校验)
- [六、首页开发](#六首页开发)
- [6.1 首页组件开发](#61-首页组件开发)
---
## 一、环境配置
### 1.1 ENV 环境配置
| 配置项 | 值 | 描述 |
| ------------------------------- | ----------------------- | ---------------------------------------------------------- |
| **VITE_IS_MICRO** | `true` | 是否是微服务架构(重要),因为单体和微服务版本共用一套前端 |
| **VITE_GLOBAL_TITLE** | `'PIGX ADMIN'` | 网站主标题(修改需要清空 localstore) |
| **VITE_FOOTER_TITLE** | `'©2024 pig4cloud.com'` | 网站页脚信息(修改需要清空 localstore) |
| **VITE_PUBLIC_PATH** | `/` | 前端访问前缀 |
| **VITE_API_URL** | `/api` | 后端请求前缀 |
| **VITE_ADMIN_PROXY_PATH** | `http://localhost:9999` | ADMIN 服务地址 |
| **VITE_PWD_ENC_KEY** | `'pigxpigxpigxpigx'` | 前端加密密钥(16 位) |
| **VITE_OAUTH2_PASSWORD_CLIENT** | `'pig:pig'` | OAUTH2 密码模式客户端信息 |
| **VITE_OAUTH2_MOBILE_CLIENT** | `'app:app'` | OAUTH2 短信客户端信息 |
| **VITE_OAUTH2_SOCIAL_CLIENT** | `'social:social'` | OAUTH2 社交登录客户端信息 |
| **VITE_VERIFY_ENABLE** | `true` | 是否开启前端滑块验证码 |
| **VITE_VERIFY_IMAGE_ENABLE** | `false` | 是否开启前端图形验证码 |
| **VITE_WEBSOCKET_ENABLE** | `false` | 是否开启 WebSocket 消息接收 |
| **VITE_REGISTER_ENABLE** | `true` | 是否开启注册 |
| **VITE_AUTO_TENANT** | `false` | 是否开启租户自动选择(根据租户域名) |
| **VITE_I18N_ENABLE** | `true` | 登录页是否开启多语言切换 |
| **VITE_DARK_MODE_ENABLE** | `true` | 登录页是否开启暗黑模式切换 |
| **VITE_ENABLE_ANTI_DEBUG** | `false` | 是否启用禁用浏览器调试功能(反爬) |
| **VITE_ANTI_DEBUG_KEY** | `pig` | 绕过反爬参数值(URL 中 `?ddtk=参数值`) |
| **VITE_GRAY_VERSION** | 无 | 对应灰度路由的 header Version |
| **VITE_API_ENC_ENABLED** | `false` | 是否开启请求加解密 |
| **VITE_TENANT_ENABLE** | `true` | 是否开启租户功能(v5.9) |
### 1.2 前端配置项说明
**配置文件**: `src/stores/themeConfig.ts`
> ⚠️ **注意**:
>
> 1. 需要每次都清理 `window.localStorage` 浏览器永久缓存
> 2. 或者点击布局配置最底部 `一键恢复默认` 按钮即可看到效果
#### 主题配置
| 配置项 | 默认值 | 描述 |
| ---------- | --------- | ----------------------------- |
| `isDrawer` | `false` | 是否开启布局配置抽屉 |
| `primary` | `#2E5CF6` | 全局主题默认 primary 主题颜色 |
| `isDark` | `false` | 是否开启深色模式 |
#### 顶栏设置
| 配置项 | 默认值 | 描述 |
| ---------------------- | --------- | ------------------------ |
| `topBar` | `#ffffff` | 默认顶栏导航背景颜色 |
| `topBarColor` | `#606266` | 默认顶栏导航字体颜色 |
| `isTopBarColorGradual` | `false` | 是否开启顶栏背景颜色渐变 |
#### 菜单设置
| 配置项 | 默认值 | 描述 |
| ----------------------- | -------------- | ------------------------ |
| `menuBar` | `#FFFFFF` | 默认菜单导航背景颜色 |
| `menuBarColor` | `#505968` | 默认菜单导航字体颜色 |
| `menuBarActiveColor` | `rgba(242...)` | 默认菜单高亮背景色 |
| `isMenuBarColorGradual` | `false` | 是否开启菜单背景颜色渐变 |
#### 界面设置
| 配置项 | 默认值 | 描述 |
| -------------------- | ------- | ------------------------ |
| `isCollapse` | `false` | 是否开启菜单水平折叠效果 |
| `isUniqueOpened` | `true` | 是否开启菜单手风琴效果 |
| `isFixedHeader` | `false` | 是否开启固定 Header |
| `isClassicSplitMenu` | `false` | 是否开启经典布局分割菜单 |
| `isLockScreen` | `false` | 是否开启自动锁屏 |
| `lockScreenTime` | `30` | 开启自动锁屏倒计时(s/秒) |
#### 界面显示
| 配置项 | 默认值 | 描述 |
| -------------------- | ------- | ---------------------------- |
| `isShowLogo` | `true` | 是否开启侧边栏 Logo |
| `isBreadcrumb` | `true` | 是否开启 Breadcrumb |
| `isTagsview` | `true` | 是否开启 Tagsview |
| `isBreadcrumbIcon` | `false` | 是否开启 Breadcrumb 图标 |
| `isTagsviewIcon` | `false` | 是否开启 Tagsview 图标 |
| `isCacheTagsView` | `true` | 是否开启 TagsView 缓存 |
| `isSortableTagsView` | `true` | 是否开启 TagsView 拖拽 |
| `isShareTagsView` | `false` | 是否开启 TagsView 共用 |
| `isFooter` | `true` | 是否开启 Footer 底部版权信息 |
| `isGrayscale` | `false` | 是否开启灰色模式 |
| `isInvert` | `false` | 是否开启色弱模式 |
| `isWartermark` | `true` | 是否开启水印 |
| `wartermarkText` | `PigX` | 水印文案 |
#### 其它设置
| 配置项 | 默认值 | 描述 |
| -------------------- | ------------------ | -------------------- |
| `tagsStyle` | `tags-style-five` | Tagsview 风格 |
| `animation` | `slide-right` | 主页面切换动画 |
| `columnsAsideStyle` | `columns-round` | 分栏高亮风格 |
| `columnsAsideLayout` | `columns-vertical` | 分栏布局风格 |
| `layout` | `defaults` | 布局设置 |
| `isRequestRoutes` | `true` | 后端控制路由是否开启 |
---
## 二、项目结构
### 2.1 目录结构
```
├── src/ # 源代码目录
│ ├── api/ # API 接口定义
│ ├── assets/ # 静态资源
│ ├── components/ # 公共组件
│ ├── directive/ # Vue 自定义指令
│ ├── hooks/ # Vue Composition API hooks
│ ├── i18n/ # 国际化相关
│ ├── layout/ # 布局组件
│ ├── locales/ # 语言包
│ ├── router/ # Vue Router 配置
│ ├── stores/ # Pinia 状态管理
│ ├── theme/ # 主题相关
│ ├── types/ # TypeScript 类型定义
│ ├── utils/ # 工具函数
│ ├── views/ # 页面组件
│ ├── App.vue # 根组件
│ └── main.ts # 应用入口文件
├── public/ # 公共静态资源
├── docker/ # Docker 相关配置
├── index.html # HTML 入口文件
├── vite.config.ts # Vite 配置
├── tsconfig.json # TypeScript 配置
├── tailwind.config.js # Tailwind CSS 配置
├── postcss.config.js # PostCSS 配置
├── package.json # 项目依赖配置
├── .env # 环境变量
├── .env.development # 开发环境变量
├── .env.development.local # 本地开发环境变量
├── .env.local # 本地环境变量
├── .eslintrc.js # ESLint 配置
└── .prettierrc.js # Prettier 配置
```
> ⚠️ **注意**:清空浏览器永久缓存或者点击 `布局配置 -> 一键恢复默认`,前提是修改了 `/src/stores/themeConfig.ts` 配置文件内容。
---
## 三、核心功能
### 3.1 国际化配置
框架内置 `中文简体`、`英文`
#### 多国语言配置
**前端配置国际化**
> 注意:页面国际化数据最好放 `同级的目录中 i18n` 里。`/@/i18n` 为框架内置,为了更好的升级,最好别添加到里面
**后端配置国际化**
与前端 i18n 配置 ts 文件格式相同,i18n 可以通过后台进行国际化管理的配置和使用。
#### 国际化使用
**页面上使用 `.vue`,`$t('xxx.xxx')`**
```vue
{{ $t('message.account.accountBtnText') }}
{{ $t('message.layout.oneTitle') }}
```
**ts 上使用 `.ts`,`i18n.global.t(xxx)`**
```typescript
import { i18n } from '/@/i18n/index';
const webTitle = i18n.global.t(router.currentRoute.value.meta.title as any);
```
**setup 里使用 ,`t(xxx)`**
```typescript
```
### 3.2 字体图标配置
#### ElementPlus 图标
使用 element plus 的图标,可去 [https://element-plus.org/zh-CN/component/icon.html](https://element-plus.org/zh-CN/component/icon.html) 复制粘贴
`` 包裹着
```vue
```
#### 阿里巴巴在线图标
**1. 创建图标项目**
1. 访问 [iconfont 官网](https://www.iconfont.cn/) 并登录
2. 创建新项目 -> 设置`FontClass/Symbol 前缀`为 `icon`,`Font Family` 为 `iconfont`
3. 添加所需图标到项目 -> 生成在线链接
**2. 设置在线链接**
代码位置:`/@/utils/setIconfont.ts`
```typescript
// `/@/utils/setIconfont.ts` cssCdnUrlList 方法中添加在线链接
// 字体图标 url (新增)
const cssCdnUrlList: Array = [
'//at.alicdn.com/t/font_2298093_y6u00apwst.css',
'//netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css',
];
```
**3. 界面中使用**
> ⚠️ **警告**:
>
> - iconfont(阿里巴巴素材库):需要添加 `iconfont` 前缀,如:`iconfont xitongshezhi`
> - font-awesome:需要添加 `fa` 前缀,如:`fa xitongshezhi`
```vue
```
#### 本地图标
支持下载 svg ,放在前端的 icons 目录
前端可通过 local-文件名的形式加载
```vue
```
#### 阿里巴巴图标库离线
为了提高系统的稳定性和加载速度,我们可以将原本使用的阿里巴巴在线图标库转换为本地离线使用。
**1. 下载图标资源包**
[点击下载 PIGX-UI 都有依赖的阿里巴巴图标](https://minio.pigx.vip/oss/202501/1737972483.zip)
**2. 创建本地图标目录**
```bash
mkdir -p pigx-ui/public/assets/iconfont
```
**3. 复制资源文件**
将下载的资源包中的以下文件复制到 `public/assets/iconfont/` 目录:
- iconfont.css
- iconfont.ttf
- iconfont.woff
- iconfont.woff2
**4. 修改配置文件**
修改 `src/utils/setIconfont.ts` 文件中的图标引用路径:
```typescript
const cssCdnUrlList: Array = [
'/assets/iconfont/iconfont.css', // 本地图标文件
'/assets/styles/font-awesome.min.css',
];
```
### 3.3 权限管理
#### 1. 组件方式
组件位置:`/@/components/auth`
**单个权限验证(:value="xxx")**
```vue
```
**多个权限验证,满足一个则显示(:value="[xxx,xxx]")**
```vue
```
**多个权限验证,全部满足则显示(:value="[xxx,xxx]")**
```vue
```
#### 2. 指令方式
指令位置:`/@/directive/authDirective.ts`
**单个权限验证(v-auth="xxx")**
```vue
新增
编辑
删除
跳转
```
**多个权限验证,满足一个则显示(v-auths="[xxx,xxx]")**
```vue
新增
编辑
```
**多个权限验证,全部满足则显示(v-auth-all="[xxx,xxx]")**
```vue
新增
编辑
```
#### 3. 函数方式
方法位置:`/@/utils/authFunction.ts`,用于方法中的判断
```typescript
```
或者在模板中使用:
```vue
...
```
### 3.4 路由管理
#### 静态路由
静态路由是指直接在前端代码中配置的路由,不需要通过后端接口动态获取。这些路由在项目编译时就已确定,适用于固定不变的页面导航结构。
在 PIGX-UI 中使用静态路由的主要原因:适合配置系统级别的页面(如登录、404 等),可以独立于后端菜单权限系统(不需要鉴权等配置)
**路由配置位置**
```
src/
└── router/
└── route.ts # 路由配置文件
```
**属性配置说明**
| 配置项 | 说明 |
| ------------- | -------------------------------------------------------------------------- |
| `title` | 菜单栏及 tagsView 栏、菜单搜索名称(国际化) |
| `isLink` | 是否超链接菜单,开启外链条件:1. isLink: 链接地址不为空 2. isIframe: false |
| `isHide` | 是否隐藏此路由 |
| `isKeepAlive` | 是否缓存组件状态 |
| `isAuth` | 是否需要认证才能进入的页面 |
| `isAffix` | 是否固定在 tagsView 栏上 |
| `isIframe` | 是否内嵌窗口,开启条件:1. isIframe: true 2. isLink:链接地址不为空 |
| `icon` | 菜单、tagsView 图标,阿里:加 `iconfont xxx`,fontawesome:加 `fa xxx` |
#### 动态路由
点击页面上的按钮可以打开新的 Tagsview 标签页,同时也可以传递参数。
**代码实现方式**
**① 菜单管理中定义隐藏菜单**
> ⚠️ 注意为角色分配该菜单的权限。
**② 点击目标按钮触发路由跳转**
```typescript
const click = () => {
router.push({
path: '/app/appArticle/form',
query: { tagsViewName: '动态路由测试', param1: '123' },
});
};
```
**③ 在跳转的页面获取请求参数**
```typescript
const route = useRoute();
onMounted(() => {
console.log(route.query.tagsViewName);
console.log(route.query.param1);
});
```
#### 菜单参数方式
在多个菜单中引用同一个路由下的组件,通过路由进行区分。
**① 配置菜单(带参)**
指向 /admin/test/index 组件
```
AAA /admin/test/1
BBB /admin/test/2
```
**② 页面获取参数**
admin/test/index.vue
```typescript
const route = useRoute();
onMounted(() => {
// test/index/参数
const parts = route.path.split('/');
const lastParam = parts[parts.length - 1];
console.log(lastParam);
});
```
### 3.5 标签页管理
#### 1. 指定标签页名称
跳转函数中指定路由参数 `tagsViewName`。
```typescript
const router = useRouter();
router.push({ path: '/xxx', query: { tagsViewName: '标签名称' } });
```
#### 2. 刷新当前页面
```typescript
import { useRoute } from 'vue-router';
import mittBus from '/@/utils/mitt';
const route = useRoute();
// 刷新当前页面
const refreshPage = () => {
mittBus.emit('onCurrentContextmenuClick', {
contextMenuClickId: 0,
...route,
});
};
```
#### 3. 关闭当前页面
```typescript
// 关闭当前页面
const closePage = () => {
mittBus.emit('onCurrentContextmenuClick', {
contextMenuClickId: 1,
...route,
});
};
```
#### 4. 关闭其它页面
```typescript
// 关闭除当前页外的其它页面
const closeOthers = () => {
mittBus.emit('onCurrentContextmenuClick', {
contextMenuClickId: 2,
...route,
});
};
```
#### 5. 关闭全部页面
```typescript
// 关闭所有页面
const closeAll = () => {
mittBus.emit('onCurrentContextmenuClick', {
contextMenuClickId: 3,
...route,
});
};
```
#### 6. 全屏显示
```typescript
// 当前页面全屏显示
const fullscreen = () => {
mittBus.emit('onCurrentContextmenuClick', {
contextMenuClickId: 4,
...route,
});
};
```
**操作 ID 说明**
| 操作 ID | 功能说明 |
| ------- | -------------- |
| 0 | 刷新当前页面 |
| 1 | 关闭当前页面 |
| 2 | 关闭其它页面 |
| 3 | 关闭全部页面 |
| 4 | 当前页全屏显示 |
### 3.6 数据状态管理
框架中数据状态使用 vuex Module 模块化进行管理,您可能需要了解 [vuex 核心概念 Module](https://next.vuex.vuejs.org/zh/guide/modules.html)
#### pinia
代码位置:`/src/stores`
相关文档:[pinia 官网](https://pinia.vuejs.org/)
相关文档:[vuex 3.x 官网](https://v3.vuex.vuejs.org/zh/)
#### 全局引入
页面模块已做全局自动引入,代码位置:`/@/store/index.ts`。
```typescript
const modulesFiles = import.meta.globEager("./modules/*.ts");
const pathList: string[] = [];
for (const path in modulesFiles) {
pathList.push(path);
}
const modules = pathList.reduce(
(modules: { [x: string]: any }, modulePath: string) => {
const moduleName = modulePath.replace(/^./modules/(.*).w+$/, "$1");
const value = modulesFiles[modulePath];
modules[moduleName] = value.default;
return modules;
},
{}
);
```
#### 定义接口
**1. interface 定义**
`/@/store/interface/index.ts`,如:路由缓存列表 `KeepAliveNamesState`
```typescript
// 路由缓存列表
export interface KeepAliveNamesState {
keepAliveNames: Array;
}
```
**2. interface 使用**
在 `/@/store/modules/` 新增 `keepAliveNames.ts`,界面写入如下代码:
```typescript
import { Module } from 'vuex';
import { KeepAliveNamesState, RootStateTypes } from '/@/store/interface/index';
const keepAliveNamesModule: Module = {
namespaced: true,
state: {
keepAliveNames: [],
},
mutations: {
// 设置路由缓存(name字段)
getCacheKeepAlive(state: any, data: Array) {
state.keepAliveNames = data;
},
},
actions: {
// 设置路由缓存(name字段)
async setCacheKeepAlive({ commit }, data: Array) {
commit('getCacheKeepAlive', data);
},
},
};
export default keepAliveNamesModule;
```
#### 使用模块
**1. 在 .ts 中使用**
```typescript
import { store } from '/@/store/index.ts';
// dispatch
store.dispatch('keepAliveNames/setCacheKeepAlive', cacheList);
// 或者 commit
// store.commit("keepAliveNames/getCacheKeepAlive", cacheList);
```
**2. 在 .vue 中使用**
```vue
在 .vue 中使用
```
---
## 四、工具函数
### 4.1 字典工具使用
#### 1. useDict 函数
字典类型对应 sys_dict 表中字典数据
```typescript
import {useDict} from '/@/hooks/dict';
const {字典类型A, 字典类型B} = useDict('字典类型A','字典类型B');
```
> ⚠️ **注意**:element-plus 的 radio 和 select 等类型组件对 value 字段有强制的数据类型要求。实体字段应该使用字符串而不是数字类型来对应字典功能使用。
#### 2. 页面使用 dict-tag
```vue
```
### 4.2 参数工具使用
#### 1. useParam 函数
| 入参 | 出参 |
| ------------------------------------ | -------------------------------------- |
| sys_public_param 表中 publicKey 字段 | sys_public_param 表中 publicValue 字段 |
```typescript
import { useParam } from '/@/hooks/param';
const param = useParam('GEN_TABLE_PREFIX');
```
#### 2. 页面使用
```vue
{{ useParam('GEN_TABLE_PREFIX') }}
```
### 4.3 通用工具函数
#### 点击复制文本
```vue
```
```typescript
const { copyText } = commonFunction();
```
#### 格式化时间
**html 代码中直接使用 parseDate parseTime 进行格式化**
```vue
{{ parseDate(scope.row.startTime) }}
{{ parseTime(scope.row.endTime) }}
```
**ts 中需要手动导入**
```typescript
import { formatDate, parseDate } from '/@/utils/formatTime';
```
#### 获取后端参数
```typescript
import params from '/@/utils/params';
let result = await params.get('参数管理中的KEY');
```
---
## 五、组件使用
### 5.1 表格组件
#### 1. useTable 函数是什么
官方对自定义 hook 定义:在 Vue 应用的概念中,"组合式函数" (Composables) 是一个利用 Vue 组合式 API 来封装和复用有状态逻辑的函数。
**useTable 函数的名称就能清晰地表达其作用,它是集成了前端 element-plus 表格的一些通用函数。**
| 方法名 | 描述 |
| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `tableStyle` | 返回包含表格样式的对象,其中包含 `cellStyle` 和 `headerCellStyle` 两个属性,分别用于设置表格单元格和表头单元格的样式 |
| `getDataList(refresh?: any)` | 获取数据列表,并可选择是否刷新当前页码。如果需要刷新,则将 `state.pagination.current` 重置为 1 |
| `sizeChangeHandle(val: number)` | 分页大小改变时触发的事件处理函数。会修改 `state.pagination` 中的 `size` 属性,并再次调用 `query()` 方法进行查询 |
| `currentChangeHandle(val: number)` | 当前页码改变时触发的事件处理函数。会修改 `state.pagination` 中的 `current` 属性,并再次调用 `query()` 方法进行查询 |
| `sortChangeHandle(column: any)` | 排序方式改变时触发的事件处理函数。根据 `column` 的内容,修改 `state.descs` 和 `state.ascs` 中的排序字段,并再次调用 `query()` 方法进行查询 |
| `downBlobFile(url: string, query: any, fileName: string)` | 用于下载文件的方法。接收三个参数:文件下载地址 `url`、请求参数 `query` 和文件名 `fileName`。返回一个 Promise 对象,用于异步处理结果 |
#### 2. 页面中如何使用
```typescript
// 使用 useTable 自动生成表格一些通用方法
const { getDataList, currentChangeHandle, sizeChangeHandle, downBlobFile, tableStyle } = useTable(state);
```
#### 3. useTable 初始化 state 如何构建
如果你想通过 useTable 生成一些通用的表格方法,那么就需要向它提供一些初始值,比如查询的 URL 和分页大小等参数。
```typescript
const state: BasicTableProps = reactive({
queryForm: {},
pageList: pageList,
});
```
**完整的 BasicTable 定义属性如下**
```typescript
export interface BasicTableProps {
// 是否在创建页面时即调用数据列表接口,默认为true
createdIsNeed?: boolean;
// 是否需要分页,默认为true
isPage?: boolean;
// 查询条件表单对象,类型为any
queryForm?: any;
// 数据列表数组
dataList?: any[];
// 分页属性对象
pagination?: Pagination;
// 数据列表,loading状态标志,默认为false
dataListLoading?: boolean;
// 数据列表多选项数组
dataListSelections?: any[];
// 数据列表查询接口api方法,接收任意数量参数,返回Promise
pageList?: (...arg: any) => Promise;
// loading标志,默认为false
loading?: Boolean;
// 多选结果数组
selectObjs?: any[];
// 排序字段数组
descs?: string[];
// 排序方式数组
ascs?: string[];
// props属性对象,类型为any
props?: any;
}
```
### 5.2 表格分页组件
#### 分页组件使用
分页组件一般和表格组件一起使用,只需要回调 useTable hook 中的函数即可
```vue
```
```typescript
const { currentChangeHandle, sizeChangeHandle } = useTable(state);
```
#### 属性说明
| 属性 | 类型 | 默认值 | 说明 |
| ----------- | -------- | ------------------------------------------- | -------------------- |
| `current` | `Number` | `1` | 当前页码 |
| `size` | `Number` | `10` | 每页展示的条数 |
| `total` | `Number` | `0` | 数据总数 |
| `pageSizes` | `Array` | `[1, 10, 20, 50, 100, 200]` | 每页展示的条数可选项 |
| `layout` | `String` | `'total, sizes, prev, pager, next, jumper'` | 分页组件的布局 |
### 5.3 表格工具栏组件
#### 工具栏组件使用
工具栏组件一般和表格组件一起使用,只需要回调 useTable hook 中的函数即可
```vue
```
```typescript
const { getDataList } = useTable(state);
```
#### 属性说明
| 属性 | 类型 | 默认值 | 说明 |
| ------------ | ------------------- | ------------------------------------------------------------------ | ---------------- |
| `showSearch` | `Boolean` | `true` | 是否显示搜索框 |
| `export` | `String or Boolean` | `当设置为true的显示,如设置为权限字符串则根据当前用户权限动态控制` | 是否导出下载按钮 |
| `search` | `Boolean` | `true` | 是否显示搜索框 |
| `gutter` | `Number` | `10` | 列表项之间的间距 |
### 5.4 上传组件
#### 普通文件上传
```vue
```
**属性说明**
| 属性名称 | 描述 | 类型 | 默认值 |
| --------------- | ------------------------- | --------- | ----------------------------------------------------------------------------------- |
| `modelValue` | 组件的值 | `string` | `Array` |
| `limit` | 数量限制 | `number` | `5` |
| `fileSize` | 文件大小限制 | `number` | `5MB` |
| `fileType` | 文件类型限制 | `Array` | `['png', 'jpg', 'jpeg', 'doc', 'xls', 'ppt', 'txt', 'pdf', 'docx', 'xlsx', 'pptx']` |
| `isShowTip` | 是否显示提示 | `boolean` | `true` |
| `uploadFileUrl` | 上传文件的 API 方法 | `string` | `'/admin/sys-file/upload'` |
| `type` | 组件类型 | `string` | `'default'` |
| `data` | 需要额外传递给 API 的数据 | `Object` | - |
| `dir` | 子目录名称 | `String` | `a/b 格式, v5.3+` |
| `autoUpload` | 是否自动上传文件 | `boolean` | `true` |
#### 图片上传
```vue
请上传头像
```
**属性说明**
| 属性名称 | 描述 | 类型 |
| --------------- | ------------------------------------------ | -------------------------------------------------------------------------------- |
| `imageUrl` | 图片地址(双向绑定,上传会更新返回此字段) | `string (必传)` |
| `uploadFileUrl` | 上传图片的 API 方法 | `string (非必传)` |
| `dir` | 子目录名称 | `String (非必传)` |
| `drag` | 是否支持拖拽上传 | `boolean (非必传,默认为 true)` |
| `disabled` | 是否禁用上传组件 | `boolean (非必传,默认为 false)` |
| `fileSize` | 图片大小限制 | `number (非必传,默认为 5M)` |
| `fileType` | 图片类型限制 | `File.ImageMimeType[] (非必传,默认为 ["image/jpeg", "image/png", "image/gif"])` |
| `height` | 组件高度 | `string (非必传,默认为 150px)` |
| `width` | 组件宽度 | `string (非必传,默认为 150px)` |
| `borderRadius` | 组件边框圆角 | `string (非必传,默认为 8px)` |
#### Excel 文件上传
```vue
```
**属性说明**
| 属性名称 | 描述 | 类型 |
| --------- | --------------------------- | -------- |
| `url` | 导入文件后台接口 | `String` |
| `title` | 弹出框标题 | `String` |
| `tempUrl` | 获取当前导如 excel 模板地址 | `String` |
### 5.5 富文本组件
Wangeditor 是一款基于 Web 的所见即所得富文本编辑器,它提供了丰富的富文本编辑功能,支持插入图片、音视频等多媒体内容,并且可以通过自定义插件扩展其功能。
#### 页面使用
```vue
```
#### 属性说明
| 属性名称 | 描述 | 类型 | 默认值 |
| --------------- | ------------------------------------------ | --------- | -------------------------- |
| `disable` | 是否禁用编辑器 | `Boolean` | `false` |
| `placeholder` | 编辑器默认占位符 | `String` | `"请输入内容..."` |
| `mode` | 编辑器模式,可选值为 default 或 simple | `String` | `default` |
| `height` | 编辑器高度 | `String` | `"310px"` |
| `getHtml` | 双向绑定的属性,用于获取编辑器中 HTML 内容 | `String` | - |
| `getText` | 双向绑定的属性,用于获取编辑器中纯文本内容 | `String` | - |
| `uploadFileUrl` | 上传文件的接口地址 | `String` | `"/admin/sys-file/upload"` |
### 5.6 代码编辑组件
#### 引入组件
```typescript
const CodeEditor = defineAsyncComponent(() => import('/@/components/CodeEditor/index.vue'));
```
#### 使用方法
```vue
```
#### Props
| 属性 | 类型 | 默认值 | 说明 |
| ------------ | ------------------ | -------- | --------------------- |
| `modelValue` | `String` | `''` | 绑定的代码内容 |
| `mode` | `String` | `'go'` | 代码语言 |
| `theme` | `String` | `'idea'` | 代码编辑器的主题 |
| `height` | `[String, Number]` | `300` | 代码编辑器的高度 |
| `options` | `Object` | `{}` | CodeMirror 的配置选项 |
| `readOnly` | `Boolean` | `false` | 是否只读 |
### 5.7 图表功能
Vue Echarts 是一个 Vue.js 的 ECharts 图表组件,对 EChart 进行了封装,简化了 Echart 图表的使用。
pigx-ui 默认引入了 vue-echarts ,业务代码中可以非常方便地使用相关的 EChart 图表组件【例如:日志管理】。
#### 快速使用
1. 访问 [ECharts 官网](https://echarts.apache.org/examples/zh/index.html#chart-type-bar),选择目标类型的图表组件,获取图表的 option 配置 JSON。
2. 访问 [vue-echarts 代码生成器](https://vue-echarts.dev/#codegen)。
#### 业务页面使用 vue-echarts
```vue
```
### 5.8 左侧查询树
```vue
```
```typescript
const QueryTree = defineAsyncComponent(() => import('/@/components/QueryTree/index.vue'));
const state = reactive({
queryList: (name: String) => {
return api({ name: name });
},
});
const handleNodeClick = (e: any) => {};
```
#### 卡槽扩展
```vue
```
#### 属性说明
| 属性 | 类型 | 默认值 | 说明 |
| ------------- | ---------- | ------------------------------------------------------ | ----------------------------------------------------------------- |
| `props` | `Object` | `{ label: 'name', children: 'children', value: 'id' }` | 树形结构的属性配置 |
| `placeholder` | `String` | `''` | 输入框的占位符 |
| `loading` | `Boolean` | `false` | 是否显示加载状态 |
| `query` | `Function` | - | 包含查询方法的函数,必须返回 Promise 类型的数据,并在组件中被调用 |
### 5.9 组织架构组件
#### 页面使用
```vue
```
#### 数据格式
```json
[
{
"type": "user",
"id": "1",
"name": "admin",
"avatar": "xx.png"
}
]
```
#### 属性说明
| 属性名 | 类型 | 默认值 | 描述 |
| ------------ | --------- | ------- | -------------------------------------------------------------------------------------------------------------- |
| `orgList` | `Array` | `[]` | 组织列表,用于显示可选的组织 |
| `type` | `String` | `user` | 类型,可选值为 user、dept、org (部门、用户 同时可选)、role、post |
| `multiple` | `Boolean` | `true` | 是否允许多选。如果为 `true`,则可以选择多个组织或用户;如果为 `false`,则只能选择一个组织或用户。默认为 `true` |
| `disabled` | `Boolean` | `false` | 是否禁用组件。如果为 `true`,则组件将不可用,用户无法进行选择。默认为 `false` |
| `selectSelf` | `Boolean` | `true` | 是否包含自身。如果为 `true`,则在可选项中包含当前用户自身;如果为 `false`,则不包含当前用户自身。默认为 `true` |
### 5.10 标签列表组件
#### 使用方法
```vue
;
```
#### 属性说明
| 属性 | 类型 | 默认值 | 说明 |
| ------------ | ---------------------------------------- | ----------- | ---------------------- |
| `modelValue` | `Array[String]` | `[]` | 双向绑定绑定的标签数组 |
| `buttonText` | `String` | `+ New Tag` | 按钮显示的文本 |
| `tagType` | `'success', 'info', 'warning', 'danger'` | - | 按钮显示类型 |
### 5.11 悬浮输入组件
```typescript
const PopoverInput = defineAsyncComponent(() => import('/@/components/PopoverInput/index.vue'));
```
```vue
点击输入
```
#### 属性说明
| 属性名称 | 描述 | 类型 | 默认值 |
| ------------- | ---------------------------------- | -------------- | --------- |
| `value` | 值 | `String` | - |
| `type` | 类型 | `String` | `'text'` |
| `width` | 宽度 | `Number` | `String` |
| `placeholder` | 提示文字 | `String` | - |
| `disabled` | 是否禁用 | `Boolean` | `false` |
| `options` | 选项列表 | `Array` | `[]` |
| `size` | 大小 | `'default'` | `'small'` |
| `limit` | 字符限制 | `Number` | `200` |
| `showLimit` | 是否显示字符限制 | `Boolean` | `false` |
| `teleported` | 是否使用传送门(teleport)进行渲染 | `Boolean` | `true` |
### 5.12 文字提示组件
```vue
浏览量
```
#### 属性说明
| 属性名称 | 描述 | 类型 | 默认值 |
| ----------- | -------- | -------- | ------------- |
| `content` | 内容 | `String` | - |
| `placement` | 放置位置 | `String` | `'top-start'` |
### 5.13 省市区街四级联动组件
#### 省市区三级联动
```typescript
const ChinaArea = defineAsyncComponent(() => import('/@/components/ChinaArea/index.vue'));
```
```vue
;
```
#### 属性说明
| 属性名称 | 描述 | 类型 |
| --------- | ------------------------- | ---------- |
| `v-model` | 双向绑定 | `String` |
| `type` | 省级 1 市 2 区 3 街道 4 | `Number` |
| `plus` | 默认 false, 不用选择某级 | `Boolean` |
| `@change` | 选中回调事件 | `Function` |
#### 完整区划数据
下载 [👉🏻 省市街区详细 SQL](https://minio.pigx.top/oss/202402/1708152046.sql),导入至 sys_area 表即可。
如果此数据(来自民政部 2023 年的数据)中不存在对应地区,您可以根据规则自行新增。请注意,编码需保持唯一。
### 5.14 表单校验
#### 表单校验使用
Form 组件允许你验证用户的输入是否符合规范,来帮助你找到和纠正错误。
Form 组件提供了表单验证的功能,只需为 rules 属性传入约定的验证规则,并将 form-Item 的 prop 属性设置为需要验证的特殊键值即可。
```typescript
const rule = ref({
字段名称: [
// 校验用户输入的长度避免超长 0-255个字符 超长
{ validator: rule.overLength, trigger: 'blur' },
// 根据字段自动查询后台是否重复
{
validator: (rule: any, value: any, callback: any) => {
validateExist(rule, value, callback, form.id !== '');
},
trigger: 'blur',
},
],
});
```
> ⚠️ **注意**:element-plus 的 radio 和 select 等类型组件对 value 字段有强制的数据类型要求。实体字段应该使用字符串而不是数字类型来对应字典功能使用。
#### 内置规则
| 函数名称 | 函数作用 |
| --------------------------- | ----------------------------------------------- |
| `validateExist` | 根据字段自动查询后台是否重复 |
| `overLength` | 校验用户输入的长度避免超长,范围为 0-255 个字符 |
| `validatorNameCn` | 校验用户输入是否为中文、英文、数字包括下划线 |
| `validatorCapital` | 校验用户输入是否为大写英文、下划线 |
| `validatorLowercase` | 校验用户输入是否为小写英文、下划线 |
| `validatorLower` | 校验用户输入是否为小写英文 |
| `checkSpace` | 校验输入是否包含首尾空白字符 |
| `validatePhone` | 校验手机号的合法性 |
| `number` | 校验输入是否为数字 |
| `letter` | 校验输入是否为字母 |
| `letterAndNumber` | 校验输入是否为字母和数字 |
| `mobilePhone` | 校验输入是否为正确格式的手机号码 |
| `letterStartNumberIncluded` | 校验输入是否以字母开头,可包含数字 |
| `noChinese` | 校验输入是否包含中文字符 |
| `chinese` | 校验输入是否为中文字符 |
| `email` | 校验输入是否为正确格式的电子邮箱 |
| `url` | 校验输入是否为正确格式的 URL |
| `regExp` | 校验输入是否符合给定的正则表达式 |
---
## 六、首页开发
### 6.1 首页组件开发
#### 开发组件
在 `src/views/home/widgets/components` 目录下创建组件
#### 挂载组件
在 `src/views/home/widgets/index.vue` 中挂载组件,将 myGrid 数组增加上一步创建的组件文件名称
```typescript
const myGrid = ['test-demo'];
```
---
## 总结
本文档汇总了 PIGX 前端技术框架的核心内容,包括:
- ✅ **环境配置**:ENV 配置、前端配置项说明
- ✅ **项目结构**:完整的目录结构说明
- ✅ **核心功能**:国际化、图标、权限、路由、标签页、状态管理
- ✅ **工具函数**:字典、参数、通用工具函数
- ✅ **组件使用**:表格、分页、上传、富文本、代码编辑、图表等 14 个常用组件
- ✅ **首页开发**:首页组件开发指南
更多详细信息请参考官方文档:[https://pig4cloud.com](https://pig4cloud.com)
---
**文档版本**: v1.0
**最后更新**: 2025-10-23
**维护团队**: PIGX 开发团队