PIGX前端技术文档汇总.md 50 KB

PIGX 前端技术文档汇总

更新日期: 2025-10-23
适配版本: 5.0 以上单体和微服务版本


目录


一、环境配置

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')

<el-button>
  <span>{{ $t('message.account.accountBtnText') }}</span>
</el-button>

<el-divider content-position="left">
  {{ $t('message.layout.oneTitle') }}
</el-divider>

ts 上使用 .tsi18n.global.t(xxx)

import { i18n } from '/@/i18n/index';

const webTitle = i18n.global.t(router.currentRoute.value.meta.title as any);

setup 里使用 ,t(xxx)

<script lang="ts">
import { defineComponent } from 'vue';
import { useI18n } from 'vue-i18n';

export default defineComponent({
  name: 'xxx',
  setup() {
    const { t } = useI18n();

    // 使用,xxx 为变量
    t(xxx)
  }
})
</script>

3.2 字体图标配置

ElementPlus 图标

使用 element plus 的图标,可去 https://element-plus.org/zh-CN/component/icon.html 复制粘贴

<el-icon></el-icon> 包裹着

<el-input type="text" :placeholder="$t('message.account.accountPlaceholder1')" v-model="ruleForm.userName" clearable autocomplete="off">
  <template #prefix>
    <el-icon class="el-input__icon"><ele-User /></el-icon>
  </template>
</el-input>

阿里巴巴在线图标

1. 创建图标项目

  1. 访问 iconfont 官网 并登录
  2. 创建新项目 -> 设置FontClass/Symbol 前缀iconFont Familyiconfont
  3. 添加所需图标到项目 -> 生成在线链接

2. 设置在线链接

代码位置:/@/utils/setIconfont.ts

// `/@/utils/setIconfont.ts` cssCdnUrlList 方法中添加在线链接
// 字体图标 url (新增)
const cssCdnUrlList: Array<string> = [
	'//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
<!-- 项目使用 -->
<i class="iconfont xitongshezhi"></i>
<!-- <i class="fa xitongshezhi"></i> -->

<!-- 或者 -->
<SvgIcon name="iconfont xitongshezhi"></SvgIcon>
<!-- <SvgIcon name="fa xitongshezhi"></SvgIcon> -->

本地图标

支持下载 svg ,放在前端的 icons 目录

前端可通过 local-文件名的形式加载

<SvgIcon name="local-gitee" :size="30" />

阿里巴巴图标库离线

为了提高系统的稳定性和加载速度,我们可以将原本使用的阿里巴巴在线图标库转换为本地离线使用。

1. 下载图标资源包

点击下载 PIGX-UI 都有依赖的阿里巴巴图标

2. 创建本地图标目录

mkdir -p pigx-ui/public/assets/iconfont

3. 复制资源文件

将下载的资源包中的以下文件复制到 public/assets/iconfont/ 目录:

  • iconfont.css
  • iconfont.ttf
  • iconfont.woff
  • iconfont.woff2

4. 修改配置文件

修改 src/utils/setIconfont.ts 文件中的图标引用路径:

const cssCdnUrlList: Array<string> = [
	'/assets/iconfont/iconfont.css', // 本地图标文件
	'/assets/styles/font-awesome.min.css',
];

3.3 权限管理

1. 组件方式

组件位置:/@/components/auth

单个权限验证(:value="xxx")

<template>
	<!-- 使用 -->
	<Auth :value="'btn.add'" />
</template>

<script setup lang="ts" name="xxx">
// 局部引入
import Auth from '/@/components/auth/auth.vue';
</script>

多个权限验证,满足一个则显示(:value="[xxx,xxx]")

<template>
	<!-- 使用 -->
	<Auths :value="['btn.addsss', 'btn.edit', 'btn.delsss', 'btn.linksss']" />
</template>

<script lang="ts">
import { defineComponent } from 'vue';
// 局部引入
import Auths from '/@/components/auth/auths.vue';

export default defineComponent({
	name: 'xxxx',
	// 局部注册
	components: { Auths },
});
</script>

多个权限验证,全部满足则显示(:value="[xxx,xxx]")

<template>
	<!-- 使用 -->
	<AuthAll :value="['btn.add', 'btn.edit', 'btn.del', 'btn.link']" />
</template>

<script lang="ts">
import { defineComponent } from 'vue';
// 局部引入
import AuthAll from '/@/components/auth/authAll.vue';

export default defineComponent({
	name: 'xxxx',
	// 局部注册
	components: { AuthAll },
});
</script>

2. 指令方式

指令位置:/@/directive/authDirective.ts

单个权限验证(v-auth="xxx")

<div v-auth="'btn.add'">
  <el-button>新增</el-button>
</div>

<div v-auth="'btn.edit'">
  <el-button>编辑</el-button>
</div>

<div v-auth="'btn.del'">
  <el-button>删除</el-button>
</div>

<div v-auth="'btn.link'">
  <el-button>跳转</el-button>
</div>

多个权限验证,满足一个则显示(v-auths="[xxx,xxx]")

<div v-auths="['btn.addsss', 'btn.edit', 'btn.delsss', 'btn.linksss']">
  <el-button>新增</el-button>
</div>

<div v-auths="['btn.add', 'btn.edit', 'btn.del', 'btn.link']">
  <el-button>编辑</el-button>
</div>

多个权限验证,全部满足则显示(v-auth-all="[xxx,xxx]")

<div v-auth-all="['btn.add', 'btn.edit', 'btn.del', 'btn.link']">
  <el-button>新增</el-button>
</div>

<div v-auth-all="['btn.add', 'btn.edit', 'btn.del', 'btn.link']">
  <el-button>编辑</el-button>
</div>

3. 函数方式

方法位置:/@/utils/authFunction.ts,用于方法中的判断

<script lang="ts" setup>
import { ElMessage } from 'element-plus';
import { auth, auths, authAll } from '/@/utils/authFunction';

// 单个权限验证
const onAuthClick = () => {
  if (!auth('btn.add')) ElMessage.error('抱歉,您没有权限!');
  else ElMessage.success('恭喜,您有权限!');
};

// 多个权限验证,满足一个则为 true
const onAuthsClick = () => {
  if (!auths(['btn.add', 'btn.edit'])) ElMessage.error('抱歉,您没有权限!');
  else ElMessage.success('恭喜,您有权限!');
};

// 多个权限验证,全部满足则为 true
const onAuthAllClick = () => {
  if (!authAll(['btn.add', 'btn.edit'])) ElMessage.error('抱歉,您没有权限!');
  else ElMessage.success('恭喜,您有权限!');
};
</script>

或者在模板中使用:

<div v-if="auth('sys_file_del')">...</div>

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 标签页,同时也可以传递参数。

代码实现方式

① 菜单管理中定义隐藏菜单

⚠️ 注意为角色分配该菜单的权限。

② 点击目标按钮触发路由跳转

const click = () => {
	router.push({
		path: '/app/appArticle/form',
		query: { tagsViewName: '动态路由测试', param1: '123' },
	});
};

③ 在跳转的页面获取请求参数

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

const route = useRoute();

onMounted(() => {
	// test/index/参数
	const parts = route.path.split('/');
	const lastParam = parts[parts.length - 1];
	console.log(lastParam);
});

3.5 标签页管理

1. 指定标签页名称

跳转函数中指定路由参数 tagsViewName

const router = useRouter();
router.push({ path: '/xxx', query: { tagsViewName: '标签名称' } });

2. 刷新当前页面

import { useRoute } from 'vue-router';
import mittBus from '/@/utils/mitt';

const route = useRoute();

// 刷新当前页面
const refreshPage = () => {
	mittBus.emit('onCurrentContextmenuClick', {
		contextMenuClickId: 0,
		...route,
	});
};

3. 关闭当前页面

// 关闭当前页面
const closePage = () => {
	mittBus.emit('onCurrentContextmenuClick', {
		contextMenuClickId: 1,
		...route,
	});
};

4. 关闭其它页面

// 关闭除当前页外的其它页面
const closeOthers = () => {
	mittBus.emit('onCurrentContextmenuClick', {
		contextMenuClickId: 2,
		...route,
	});
};

5. 关闭全部页面

// 关闭所有页面
const closeAll = () => {
	mittBus.emit('onCurrentContextmenuClick', {
		contextMenuClickId: 3,
		...route,
	});
};

6. 全屏显示

// 当前页面全屏显示
const fullscreen = () => {
	mittBus.emit('onCurrentContextmenuClick', {
		contextMenuClickId: 4,
		...route,
	});
};

操作 ID 说明

操作 ID 功能说明
0 刷新当前页面
1 关闭当前页面
2 关闭其它页面
3 关闭全部页面
4 当前页全屏显示

3.6 数据状态管理

框架中数据状态使用 vuex Module 模块化进行管理,您可能需要了解 vuex 核心概念 Module

pinia

代码位置:/src/stores

相关文档:pinia 官网

相关文档:vuex 3.x 官网

全局引入

页面模块已做全局自动引入,代码位置:/@/store/index.ts

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

// 路由缓存列表
export interface KeepAliveNamesState {
	keepAliveNames: Array<string>;
}

2. interface 使用

/@/store/modules/ 新增 keepAliveNames.ts,界面写入如下代码:

import { Module } from 'vuex';
import { KeepAliveNamesState, RootStateTypes } from '/@/store/interface/index';

const keepAliveNamesModule: Module<KeepAliveNamesState, RootStateTypes> = {
	namespaced: true,
	state: {
		keepAliveNames: [],
	},
	mutations: {
		// 设置路由缓存(name字段)
		getCacheKeepAlive(state: any, data: Array<string>) {
			state.keepAliveNames = data;
		},
	},
	actions: {
		// 设置路由缓存(name字段)
		async setCacheKeepAlive({ commit }, data: Array<string>) {
			commit('getCacheKeepAlive', data);
		},
	},
};

export default keepAliveNamesModule;

使用模块

1. 在 .ts 中使用

import { store } from '/@/store/index.ts';

// dispatch
store.dispatch('keepAliveNames/setCacheKeepAlive', cacheList);

// 或者 commit
// store.commit("keepAliveNames/getCacheKeepAlive", cacheList);

2. 在 .vue 中使用

<template>
	<div v-if="getThemeConfig.isLockScreen">在 .vue 中使用</div>
</template>

<script lang="ts">
import { computed, defineComponent } from 'vue';
import { useStore } from '/@/store/index';

export default defineComponent({
	name: 'app',
	setup() {
		const store = useStore();
		// 获取布局配置信息
		const getThemeConfig = computed(() => {
			return store.state.themeConfig.themeConfig;
		});
	},
});
</script>

四、工具函数

4.1 字典工具使用

1. useDict 函数

字典类型对应 sys_dict 表中字典数据

import {useDict} from '/@/hooks/dict';

const {字典类型A, 字典类型B} = useDict('字典类型A','字典类型B');

⚠️ 注意:element-plus 的 radio 和 select 等类型组件对 value 字段有强制的数据类型要求。实体字段应该使用字符串而不是数字类型来对应字典功能使用。

2. 页面使用 dict-tag

<el-table-column>
  <template #default="scope">
    <dict-tag :options="字典类型" :value="scope.row.xx"></dict-tag>
  </template>
</el-table-column>

4.2 参数工具使用

1. useParam 函数

入参 出参
sys_public_param 表中 publicKey 字段 sys_public_param 表中 publicValue 字段
import { useParam } from '/@/hooks/param';
const param = useParam('GEN_TABLE_PREFIX');

2. 页面使用

{{ useParam('GEN_TABLE_PREFIX') }}

4.3 通用工具函数

点击复制文本

<button @click="copyText('文案内容')">复制</button>
const { copyText } = commonFunction();

格式化时间

html 代码中直接使用 parseDate parseTime 进行格式化

<el-table-column :label="t('tenant.startTime')" prop="startTime" show-overflow-tooltip>
  <template #default="scope">
    <span>{{ parseDate(scope.row.startTime) }}</span>
  </template>
</el-table-column>

<el-table-column :label="t('tenant.endTime')" prop="endTime" show-overflow-tooltip>
  <template #default="scope">
    <span>{{ parseTime(scope.row.endTime) }}</span>
  </template>
</el-table-column>

ts 中需要手动导入

import { formatDate, parseDate } from '/@/utils/formatTime';

获取后端参数

import params from '/@/utils/params';

let result = await params.get('参数管理中的KEY');

五、组件使用

5.1 表格组件

1. useTable 函数是什么

官方对自定义 hook 定义:在 Vue 应用的概念中,"组合式函数" (Composables) 是一个利用 Vue 组合式 API 来封装和复用有状态逻辑的函数。

useTable 函数的名称就能清晰地表达其作用,它是集成了前端 element-plus 表格的一些通用函数。

方法名 描述
tableStyle 返回包含表格样式的对象,其中包含 cellStyleheaderCellStyle 两个属性,分别用于设置表格单元格和表头单元格的样式
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.descsstate.ascs 中的排序字段,并再次调用 query() 方法进行查询
downBlobFile(url: string, query: any, fileName: string) 用于下载文件的方法。接收三个参数:文件下载地址 url、请求参数 query 和文件名 fileName。返回一个 Promise 对象,用于异步处理结果

2. 页面中如何使用

// 使用 useTable 自动生成表格一些通用方法
const { getDataList, currentChangeHandle, sizeChangeHandle, downBlobFile, tableStyle } = useTable(state);

3. useTable 初始化 state 如何构建

如果你想通过 useTable 生成一些通用的表格方法,那么就需要向它提供一些初始值,比如查询的 URL 和分页大小等参数。

const state: BasicTableProps = reactive<BasicTableProps>({
	queryForm: {},
	pageList: pageList,
});

完整的 BasicTable 定义属性如下

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<any>;
	// loading标志,默认为false
	loading?: Boolean;
	// 多选结果数组
	selectObjs?: any[];
	// 排序字段数组
	descs?: string[];
	// 排序方式数组
	ascs?: string[];
	// props属性对象,类型为any
	props?: any;
}

5.2 表格分页组件

分页组件使用

分页组件一般和表格组件一起使用,只需要回调 useTable hook 中的函数即可

<pagination v-bind="state.pagination" @current-change="currentChangeHandle" @size-change="sizeChangeHandle"></pagination>
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 中的函数即可

<right-toolbar v-model:showSearch="showSearch" :export="'sys_user_export'" @exportExcel="exportExcel" @queryTable="getDataList" />
const { getDataList } = useTable(state);

属性说明

属性 类型 默认值 说明
showSearch Boolean true 是否显示搜索框
export String or Boolean 当设置为true的显示,如设置为权限字符串则根据当前用户权限动态控制 是否导出下载按钮
search Boolean true 是否显示搜索框
gutter Number 10 列表项之间的间距

5.4 上传组件

普通文件上传

<upload-file @change="success" />

属性说明

属性名称 描述 类型 默认值
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

图片上传

<upload-img v-model:imageUrl="formData.avatar" borderRadius="50%">
  <template #empty>
    <el-icon><Avatar /></el-icon>
    <span>请上传头像</span>
  </template>
</upload-img>

属性说明

属性名称 描述 类型
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 文件上传

<upload-excel
	ref="excelUploadRef"
	:title="$t('sysuser.importUserTip')"
	temp-url="/admin/sys-file/local/file/user.xlsx"
	url="/admin/user/import"
	@refreshDataList="getDataList"
/>

属性说明

属性名称 描述 类型
url 导入文件后台接口 String
title 弹出框标题 String
tempUrl 获取当前导如 excel 模板地址 String

5.5 富文本组件

Wangeditor 是一款基于 Web 的所见即所得富文本编辑器,它提供了丰富的富文本编辑功能,支持插入图片、音视频等多媒体内容,并且可以通过自定义插件扩展其功能。

页面使用

<editor v-model:get-html="form.content" />

属性说明

属性名称 描述 类型 默认值
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 代码编辑组件

引入组件

const CodeEditor = defineAsyncComponent(() => import('/@/components/CodeEditor/index.vue'));

使用方法

<template>
	<div>
		<CodeEditor v-model="code" mode="go" theme="idea" :readOnly="false" :height="300" />
	</div>
</template>

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 官网,选择目标类型的图表组件,获取图表的 option 配置 JSON。

  2. 访问 vue-echarts 代码生成器

业务页面使用 vue-echarts

<template>
	<v-chart class="h-80 w-full" :option="option" />
</template>

<script setup lang="ts" name="demo-chart">
// 直接复制 vue-echart codegen 生成的 vue 代码部分
import { use, reactive } from 'echarts/core'
import {
  BarChart
} from 'echarts/charts'
import {
  GridComponent
} from 'echarts/components'
import {
  CanvasRenderer
} from 'echarts/renderers'

use([
  GridComponent,
  BarChart,
  CanvasRenderer
])

// 定义 JSON
const option = reactive(复制 EChart option JSON)
</script>

5.8 左侧查询树

<query-tree :query="state.queryList" @node-click="handleNodeClick">
</query-tree>
const QueryTree = defineAsyncComponent(() => import('/@/components/QueryTree/index.vue'));

const state = reactive({
	queryList: (name: String) => {
		return api({ name: name });
	},
});

const handleNodeClick = (e: any) => {};

卡槽扩展

<query-tree>
  <template #default="{ node, data }">
  </template>
</query-tree>

属性说明

属性 类型 默认值 说明
props Object { label: 'name', children: 'children', value: 'id' } 树形结构的属性配置
placeholder String '' 输入框的占位符
loading Boolean false 是否显示加载状态
query Function - 包含查询方法的函数,必须返回 Promise 类型的数据,并在组件中被调用

5.9 组织架构组件

页面使用

<template>
	<org-selector v-model:orgList="userList" type="user" :multiple="false" />
</template>

<script setup>
import orgSelector from '/@/components/OrgSelector/index.vue';
</script>

数据格式

[
	{
		"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 标签列表组件

使用方法

<tag-list buttonText="+手机号" v-model="phoneList" />
;

<script setup>
const phoneList = ref([]);
</script>

属性说明

属性 类型 默认值 说明
modelValue Array[String] [] 双向绑定绑定的标签数组
buttonText String + New Tag 按钮显示的文本
tagType 'success', 'info', 'warning', 'danger' - 按钮显示类型

5.11 悬浮输入组件

const PopoverInput = defineAsyncComponent(() => import('/@/components/PopoverInput/index.vue'));
<popover-input @confirm="onConfirm">
  <template #default>
    <el-button> 点击输入 </el-button>
  </template>
</popover-input>

属性说明

属性名称 描述 类型 默认值
value String -
type 类型 String 'text'
width 宽度 Number String
placeholder 提示文字 String -
disabled 是否禁用 Boolean false
options 选项列表 Array<any[]> []
size 大小 'default' 'small'
limit 字符限制 Number 200
showLimit 是否显示字符限制 Boolean false
teleported 是否使用传送门(teleport)进行渲染 Boolean true

5.12 文字提示组件

<el-form-item label="初始浏览量" prop="visit">
  <template #label>
    浏览量<tip content="初始值" />
  </template>
</el-form-item>

属性说明

属性名称 描述 类型 默认值
content 内容 String -
placement 放置位置 String 'top-start'

5.13 省市区街四级联动组件

省市区三级联动

const ChinaArea = defineAsyncComponent(() => import('/@/components/ChinaArea/index.vue'));
<china-area v-model="data" @change="handleChange" />
;

<script setup>
// 双向绑定数据 自动回显: 北京市/市辖区/东城区
const data = ref('11,1101,110101');

// 可选 输出: 11,1101,110101
const handleChange = (val: String) => {};
</script>

属性说明

属性名称 描述 类型
v-model 双向绑定 String
type 省级 1 市 2 区 3 街道 4 Number
plus 默认 false, 不用选择某级 Boolean
@change 选中回调事件 Function

完整区划数据

下载 👉🏻 省市街区详细 SQL,导入至 sys_area 表即可。

如果此数据(来自民政部 2023 年的数据)中不存在对应地区,您可以根据规则自行新增。请注意,编码需保持唯一。

5.14 表单校验

表单校验使用

Form 组件允许你验证用户的输入是否符合规范,来帮助你找到和纠正错误。

Form 组件提供了表单验证的功能,只需为 rules 属性传入约定的验证规则,并将 form-Item 的 prop 属性设置为需要验证的特殊键值即可。

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 数组增加上一步创建的组件文件名称

const myGrid = ['test-demo'];

总结

本文档汇总了 PIGX 前端技术框架的核心内容,包括:

  • 环境配置:ENV 配置、前端配置项说明
  • 项目结构:完整的目录结构说明
  • 核心功能:国际化、图标、权限、路由、标签页、状态管理
  • 工具函数:字典、参数、通用工具函数
  • 组件使用:表格、分页、上传、富文本、代码编辑、图表等 14 个常用组件
  • 首页开发:首页组件开发指南

更多详细信息请参考官方文档:https://pig4cloud.com


文档版本: v1.0
最后更新: 2025-10-23
维护团队: PIGX 开发团队