针对vue3公共组件库的使用介绍如下
注意node版本需要固定为21.x.x
需要更新vscode版本,如果vscode版本没有检测更新按钮,需要下载system installer版本的vscode,下载路径为https://code.visualstudio.com/Download
建议安装yarn命令管理工具、node版本管理工具nvm
element-plus固定版本号为xxx,目前暂无需求
下面演示如有使用命令的,全部使用yarn演示
yarn add hdl-global-com element-plus jsencrypt qs sortablejs @icon-park/vue-next axios pinia vite-plugin-qiankun vue-router screenfull yarn add @types/node @types/qs @types/sortablejs sass unplugin-auto-import vite-plugin-eslint2 -D
import hdlGlobalCom from 'hdl-global-com'
import 'hdl-global-com/themes/index.scss';
app.use(hdlGlobalCom)
// 或者针对性的设置一下初始值
app.use(hdlGlobalCom, {
localStorageKey: Partial<{
HDL_TOKEN: string; // token的标识 默认为HDL_TOKEN
HDL_USER: string; // 用户信息的标识 默认为HDL_USER
HDL_MENU: string; // 当前保存的菜单项
HDL_MENU_SN: string; // 浏览器获取菜单sn的标识 默认为HDL_MENU_SN
HDL_USER_NAME: string; // 用户名
HDL_PWD: string; // 密码
}>;
hdlLogin: Partial<{ // 登录组件的全局配置类型注解
loginSuccessRoute: string; // 登录成功后的默认路由
loginRoute: string; // 登录页的路由
refreshRouteName: string; // 刷新路由的名称
qkMenuType: string; // qiankun的菜单类型
}>;
hdlAxios: Partial<{ // axios请求配置
}>;
hdlTable: Partial<{ // 表格组件 用于表格的一些配置
operateColConfig: TableColumn; // 操作列配置
authVal: number; // 值为authVal的时候显示
onlyShowVal: boolean; // 值为onlyShowVal的时候显示
pageSizes: number[]; // 分页器每页显示个数
pageSize: number; // 分页器每页显示个数
popupPageSizes: number[]; // 弹窗分页器每页显示个数
popupPageSize: number; // 弹窗分页器每页显示个数
}>;
hdlMenus: Partial<{ // 菜单组件
width: number; // 菜单展开后的宽度
collapseWidth: number; // 菜单伸缩后的宽度
}>;
hdlSearch: Partial<{ // 筛选框组件
width: number; // 筛选框的默认宽度
}>;
hdlForm: Partial<{ // 表单组件
labelWidth: string; // 表单的label宽度
}>;
hdlTree: Partial<{ // 树组件
width: number; // 初始树宽度
minWidth: number; // 最小宽度
maxWidth: number; // 最大宽度
}>;
})
界面头部内容区域
- template使用
<hdl-header
v-model:collapse="collapse"
:avatar="userInfo.avatar || ''"
:user-name="userInfo.othername || userInfo.username"
@get-menu-status="getMenuStatus"
/>
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
collapse | Boolean | true | 是否默认折叠菜单 |
collapseWidth | Number | 80 | 折叠菜单宽度 |
width | Number | 240 | 展开菜单宽度 |
avatar | String | - | 用户头像的唯一标识 必填 |
userName | String | 默认用户 | 当前登录的用户名 |
事件 | 参数 | 类型 | 说明 |
---|---|---|---|
get-menu-status | width | number | 获取菜单宽度 |
update:collapse | collapse | boolean | 更新菜单状态 |
公共按钮组件,可动态配置出权限按钮,按钮形式包括:普通按钮、下拉按钮、上传按钮、提示按钮等
- template使用
<hdl-btn v-model="btnData"></hdl-btn>
- 普通按钮
import { ButtonType } from 'hdl-global-com';
const optButton = ref<ButtonType[]>([
{
type: 'default', // 普通按钮可省略这个配置
name: '普通按钮',
func: () => {
console.log('xxx')
},
auth: 'xxx'
}
]);
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
type | default | default | 使用默认值即可 |
name | string | 必填 | 按钮名字 |
icon | DefineComponent | - | 按钮图标 |
auth | string | 必填 | 按钮权限 |
func | (...args: any[]) => any | 必填 | 回调函数 |
class | primary,success,info,warning,danger | 自动计算,初始为primary | 样式类名 |
show | Ref<boolean> | true | 逻辑显示隐藏,显示时权限小于auth,隐藏时权限大于auth |
loading | Ref<boolean> | false | loading状态 |
developShow | boolean | false | 强制显示,不走任何权限 |
- 下拉按钮
import { ButtonType } from 'hdl-global-com';
const optButton = ref<ButtonType[]>([
{
type: 'select',
name: '更多',
children: [{
name: '下载',
auth: 'down',
func: () => {
console.log('xxx')
}
}]
}
]);
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
name | string | 必填 | 按钮名字 |
type | select | 必填 | 需要设置为select |
class | primary,success,info,warning,danger | 自动计算,初始为primary | 样式类名 |
children | Array<any> | 必填 | 子按钮 |
children子按钮API
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
name | string | 必填 | 按钮名字 |
auth | string | 必填 | 按钮权限 |
func | (...args: any[]) => any | 必填 | 回调函数 |
icon | DefineComponent | - | 按钮图标 |
show | Ref<boolean> | true | 逻辑显示隐藏,显示时权限小于auth,隐藏时权限大于auth |
loading | Ref<boolean> | false | loading状态 |
developShow | boolean | false | 强制显示,不走任何权限 |
- 上传按钮
import { ButtonType } from 'hdl-global-com';
const optButton = ref<ButtonType[]>([
{
type: 'upload',
name: '上传',
icon: 'icon-xinzeng',
auth: 'xxx',
props: {
action: 'https://jsonplaceholder.typicode.com/posts/',
headers: {
Authorization: 'Bearer token'
}
}
}
]);
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
type | upload | 必填 | 需要设置为upload |
name | string | 必填 | 按钮名字 |
auth | string | 必填 | 按钮权限 |
icon | DefineComponent | - | 按钮图标 |
class | primary,success,info,warning,danger | 自动计算,初始为primary | 样式类名 |
show | Ref<boolean> | true | 逻辑显示隐藏,显示时权限小于auth,隐藏时权限大于auth |
loading | Ref<boolean> | false | loading状态 |
developShow | boolean | false | 强制显示,不走任何权限 |
props | Partial | {} | 参考el-upload的属性 |
- 提示按钮
import { BpgBtnType } from 'hdl-global-com';
const optButton = ref<BpgBtnType.OptButtonType[]>([
{
name: '提示',
auth: '',
type: 'tooltip',
icon: 'icon-xinzeng',
props: {
content: '这是一个提示'
},
func: () => {
console.log('xxx')
}
}
]);
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
type | tooltip | 必填 | 需要设置为tooltip |
name | string | 必填 | 按钮名字 |
auth | string | 必填 | 按钮权限 |
icon | DefineComponent | - | 按钮图标 |
class | primary,success,info,warning,danger | 自动计算,初始为primary | 样式类名 |
show | Ref<boolean> | true | 逻辑显示隐藏,显示时权限小于auth,隐藏时权限大于auth |
loading | Ref<boolean> | false | loading状态 |
developShow | boolean | false | 强制显示,不走任何权限 |
props | Partial | {} | 参考el-tooltip的属性 |
func | (...args: any[]) => any | 必填 | 回调函数 |
针对于周期类型的计划、任务等需求下使用,可灵活的配置任何时间段的周期调度
<template>
<bpgCron v-model="expression" />
</template>
<script lang="ts" setup>
const expression = ref('0 0 0/1 * * ?');
</script>
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
modelValue | string | '' | 克隆表达式 |
tabVal | second,min,hour,day,month,weak,year | hour | 默认选中的tab |
hideComponent | [second,min,hour,day,month,weak,year] | [] | 需要隐藏的tab |
readonly | boolean | false | 是否只读 |
可动态配置出页面过滤条件,并可实现条件的显示隐藏、label文字更改、属性更改等效果
- template使用
<hdl-search v-model="searchData" @search="search"></hdl-search>
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
auth | string | '' | 父级权限,如果需要权限控制,必须设置这个 |
modelValue | SearchType[] | 必填 | 筛选条件配置 |
hideBtn | Boolean | 否 | 是否隐藏筛选按钮 |
refreshToSearch | Boolean | 否 | 点击重置按钮后,是否立即执行搜索回调 |
事件 | 参数 | 类型 | 说明 |
---|---|---|---|
search | width | number | 点击搜索 |
refresh | collapse | boolean | 点击重置 |
update:modelValue | val | SearchType[] | 更新筛选框配置 |
- 文本框
import { SearchType, useUUID } from 'hdl-global-com'
const model = ref('');
const optFilter = ref<SearchType[]>([{
id: useUUID(),
comName: 'el-input',
model: model,
props: {
placeholder: '请输入xxx'
},
}])
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
id | string | - | 唯一标识,必填 |
model | Ref<any> | - | 绑定的数据,必填 |
auth | string | '' | 权限,如果需要权限控制,必须设置这个 |
onlyAuth | boolean | false | 是否只在某个用户下展示 |
show | Ref<boolean> | true | 逻辑显示隐藏,显示时权限小于auth,隐藏时权限大于auth |
comName | el-input | el-input | 组件名,必填 |
props | Partial<InputProps> | {} | 组件属性 |
emits | blur,focus,change,input,clear | - | 组件事件 |
- 下拉框
import { SearchType, useUUID } from 'hdl-global-com'
const model = ref('');
const optFilter = ref<SearchType[]>([{
id: useUUID(),
comName: 'el-select',
model: model,
children: {
comName: 'el-option',
data: [],
props: {
value: 'value',
label: 'label'
}
},
props: {
placeholder: '请选择xxx'
}
}])
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
id | string | - | 唯一标识,必填 |
model | Ref<any> | - | 绑定的数据,必填 |
auth | string | '' | 权限,如果需要权限控制,必须设置这个 |
onlyAuth | boolean | false | 是否只在某个用户下展示 |
show | Ref<boolean> | true | 逻辑显示隐藏,显示时权限小于auth,隐藏时权限大于auth |
comName | el-select | el-select | 组件名,必填 |
props | Partial<SelectContext['props']> | {} | 组件属性 |
emits | change,visibleChange,removeTag,clear,blur,focus | - | 组件事件 |
children.comName | el-option | el-option | 子组件名,必填 |
children.data | any | [] | 子组件数据 |
children.props | value,label,disabled | {} | 子组件属性 |
- 级联选择框
import { SearchType, useUUID } from 'hdl-global-com'
const model = ref<string[]>([]);
const optFilter = ref<SearchType[]>([{
id: useUUID(),
comName: 'el-cascader',
model: model,
props: {
...
},
emits: {
...
}
}])
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
id | string | - | 唯一标识,必填 |
model | Ref<any> | - | 绑定的数据,必填 |
auth | string | '' | 权限,如果需要权限控制,必须设置这个 |
onlyAuth | boolean | false | 是否只在某个用户下展示 |
show | Ref<boolean> | true | 逻辑显示隐藏,显示时权限小于auth,隐藏时权限大于auth |
comName | el-cascader | el-cascader | 组件名,必填 |
props | 具体查看官网 | {} | 组件属性 |
emits | 具体查看官网 | - | 组件事件 |
- 其余类型请举一反三
主要是为了统一设置labelWidth,其余功能与官方的el-form一模一样
<template>
<hdl-form ref="hdlFormRef" :model="formVal" :rules="rules">
<el-form-item label="姓名" prop="name">
<el-input v-model="formVal.name" />
</el-form-item>
...
</-form>
</template>
<script lang="ts" setup>
import { FormRules } from 'element-plus'
const formVal = reactive({
name: ''
})
const rules = reactive<FormRules>({
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }]
})
const hdlFormRef = useTemplateRef('hdlFormRef');
console.log(hdlFormRef) // 方法全在这里
</script>
全项目就用一次,用于菜单展示
<template>
<hdl-menus
:user-name="userInfo.username || ''"
:system-sn="systemSn"
:collapse="collapse"
@get-system-name="getSystemName"
/>
</template>
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
userName | string | 必填 | 用户名 |
systemSn | string | 必填 | 当前系统的标识 |
collapse | boolean | 必填 | 当前菜单的折叠状态 |
事件 | 参数 | 类型 | 说明 |
---|---|---|---|
getSystemName | name | string | 获取当前系统的名称 |
数据表单el-table的封装,更便捷的使用与灵活的权限控制
- 不分页使用
<template>
<hdlTable :data="tableData" :columns="columns" />
</template>
<script lang="ts" setup>
import { TableColumn } from 'hdl-global-com'
const tableData = ref<any[]>([])
const columns = ref<TableColumn<any>>([])
</script>
- 分页使用
<template>
<hdl-table :data="tableData" :columns="columns">
<template #pagination="pageScope">
<el-pagination v-bind="pageScope" v-model:page-size="pageSize" v-model:current-page="currentPage" :total="total"></el-pagination>
</template>
</hdl-table>
</template>
<script lang="ts" setup>
import { AxiosListResultType, usePagination } from 'hdl-global-com'
const columns = ref<TableColumn<AxiosListResultType['xxx']>>([{
label: '名称',
prop: 'taskName'
}, {
label: '开始时间',
prop: 'createTime'
}])
const { tableData, total, pageSize, currentPage, getTableData } = usePagination({ // 分页获取公司列表信息
url: 'xxx'
});
</script>
- 插槽使用
<template>
<hdlTable :data="tableData" :columns="columns">
<template #name="{ colData }">
<el-table-column v-bind="colData">
<template #default="{ row }">
<span>我的名字是:{{ row.name }}</span>
</template>
</el-table-column>
</template>
</hdlTable>
</template>
<script lang="ts" setup>
import { TableColumn } from 'hdl-global-com'
const tableData = ref<any[]>([])
const columns = ref<TableColumn<any>>([
{
prop: 'name',
label: '名称',
slot: true
}
])
</script>
- API说明
hdlTable的配置说明
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
isPopup | boolean | false | 是否是弹窗中的表格 |
auth | string | '' | 父级权限 |
columns | TableColumn | [] | 表格列配置 |
data | any[] | [] | 表格数据 |
... | ... | .... | 更多方法与属性参考el-table配置 |
columns的配置说明
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
type | default,selection,index,expand,move | default | 列类型 |
slot | boolean | false | 是否需要使用插槽 |
show | boolean | true | 逻辑显示隐藏 |
auth | string | '' | 列权限标识,需配合pAuth使用 |
onlyAuth | boolean | false | 在auth权限为显示的情况下,只有配置了onlyAuth也为显示,此列才有权限显示 |
... | ... | ... | 更多属性配置参考el-table-column |
用于树形数据的展示
<template>
<hdl-tree ref="hdlTreeRef" :data="treeData" node-key="code" :input-props="{ placeholder: '请输入公司名称' }" @current-change="currentChange"></hdl-tree>
</template>
<script lang="ts" setup>
const treeData = ref<any[]>([]);
const currentChange = (data: any) => { // 树节点选择的时候
console.log(data)
};
</script>
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
showFilter | boolean | false | 是否显示搜索框 |
inputProps | object | {} | 搜索框的配置 |
treeWidth | string | '' | 一般不配置或者配置为100% |
nodeKey | string | '' | 必填,树节点的唯一标识 |
... | ... | ... | 更多属性参考el-tree配置 |
用于树右侧的宽度拖拽
<div class="hdl-tree-bar" v-tree-drag></div>
用于控制表单项的权限
<hdl-form :model="form">
<el-row :gutter="15">
<el-col :span="12" v-form-auth:[callback]="['sysRole', 'formRoleName', true]">
<el-form-item label="名称" v-bind="nameProps.formItemProps">
<el-input v-model="form.name" v-bind="nameProps.props" />
</el-form-item>
</el-col>
</el-row>
</hdl-form>
<script lang="ts" setup>
const nameProps = reactive({
props: {},
formItemProps: {}
});
const callback = (params: Record<string, any>) => {
nameProps.props = params.props || {};
nameProps.formItemProps = params.formItemProps || {};
};
</script>
v-form-auth:D="[A, B, C]"举例
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
A | string | '' | 父级权限标识 |
B | string | '' | 子级权限标识 |
C | boolean | false | 在auth权限为显示的情况下,只有配置了onlyAuth也为显示,此列才有权限显示 |
D | (params: Record<string, any>) => void | - | 权限判断完的回调函数 |
监听DOM尺寸变化,常用于echarts的重绘
<template>
<div v-resize="domResize">
echarts
</div>
</template>
<script setup lang="ts">
const domResize = (width: number, height: number) => {
console.log(width, height)
}
</script>
方法名 | 说明 | 参数 | 返回类型 |
---|---|---|---|
useUUID | 获取随机字符串 | len:字符串长度,默认为6 | string |
useDebounce | 防抖 | fn: 需要防抖的函数 params.delay:防抖延迟时间 params.isImmediate:是否立即执行 |
(...args: any[]) => void |
useSleep | 等待函数 | time:等待时长,默认为0毫秒 | Promise<void> |
useFormatDate | 日期格式化 | date:待格式化的日期 formatType:输出格式,默认为yyyy-MM-dd |
string |
useGetDictChild | 获取字典项数据 | code:字典编码 | Promise<AxiosDataType['getDictChild']> |
统一封装请求方法,并增加ts类型注解 在当前项目中,进行useAxios的方法注册,并传递url信息与ts的注解文件 后续该项目中的所有请求,直接使用注册后的axios即可
import { useAxios } from 'hdl-global-com';
import apiUrlList from './apiUrl';
import { ApiUrlKeyType, AxiosResponseType } from './type';
export const axios = useAxios<ApiUrlKeyType, AxiosResponseType>(apiUrlList);
export default axios;
/* xxx使用 */
axios({
...
})
统一封装分页请求表格数据 在当前项目中,需要进行usePagination的方法注册,传递当前的请求函数与ts注解文件 后续该项目中的所有分页请求,直接使用注册后的usePagination即可
/* 当前项目的utils/index.ts文件中 */
import { usePagination as pagination } from 'hdl-global-com';
import axios from '@axios/index';
import { AxiosResponseType, AxiosResultType } from '@axios/type';
export const usePagination = pagination<AxiosResponseType, AxiosResultType>(axios);
/* xxx使用 */
import { usePagination } from '@utils/index';
const { total, pageSize, currentPage, tableData } = usePagination({
url: 'xxx'
})
参数说明
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
url | string | 必填 | 请求的url |
data | object | {} | 请求参数 |
method | string | get | 请求方法体 |
isPopup | boolean | false | 是否是弹窗中的表格 |
immediate | boolean | true | 是否立即执行请求 |
返回值说明
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
total | number | 0 | 数据总量 |
pageSize | number | isPopup为true时为5,false为20 | 每页数量 |
currentPage | number | 1 | 页索引 |
tableData | any[] | [] | 表格数据 |
getTableData | () => void | - | 手动调用请求表格数据 immediate为false时需要使用此函数 |
常用于父子系统之间的事件交互
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import { useEventBus } from 'hdl-global-com'
const routes: RouteRecordRaw[] = [{
path: '/',
component: () => import('@/views/index/index.vue'),
redirect: '/login',
name: 'default',
children: [{
path: '/home',
name: 'home',
component: () => import('@views/home/index.vue')
}, ...]
}, {
path: '/login',
name: 'login',
component: () => import('@/views/login/index.vue')
}]
const router = createRouter({
history: createWebHistory(),
routes
})
useEventBus().on('logout', () => {
router.push('/login')
})
export default router
常用于编辑表单时的数据回显
<template>
<hdlTable @update="updateForm"></hdlTable>
</template>
<script lang="ts" setup>
import { useAssign } from 'hdl-global-com'
const formVal = reactive({
name: ''
}) // 表单数据
const tableSelectRow = reactive({
name: '张三',
age: 18
}) // 当前选中的表格行数据
const updateForm = () => { // 点击编辑按钮时
Object.assign(formVal, useAssign(formVal, tableSelectRow))
console.log(formVal)
// 输出 { name: 张三 }
}
</script>
统一封装websocket,更便捷的调用与监听 需要在该项目中,进行useWs的注册
- 注册
/* utils/index.ts中 */
import { useWs } from 'hdl-global-com';
import apiUrlList from '@axios/apiUrl';
export const { useInitWs, useWsClose, useWsError, useWsMsg, useWsOpen, useWsSend } = useWs(apiUrlList);
- useInitWs API说明
useInitWs({
url: 'xxx',
data: ''
})
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
params.url | string | 必填 | ws的请求路径 |
params.data | string | '' | 请求参数 |
- useWsOpen API说明
// 举例
const C = useWsOpen(A, B)
//使用
const stopListenOpen = useWsOpen('xxx', () => {
console.log('ws已打开')
})
onUnmounted(stopListenOpen)
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
A | string | '' | 你需要监听哪个ws的打开 参考useInitWs里配置的url |
B | () => void | - | ws成功打开时的回调函数 |
C | () => void | - | 停止监听ws打开,界面卸载时需要执行这个函数 |
- useWsSend API说明
// 举例
useWsSend(A, B, {
interval: C,
isHeartbeat: D
})
// 使用
useWsSend('xxx', '', {
interval: 30000,
isHeartbeat: true
})
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
A | string | '' | 你需要给哪个ws发送数据 参考useInitWs里配置的url |
B | string | '' | 数据源 |
C | number | - | 心跳间隔时间,单位毫秒 |
D | boolean | false | 是否对当前的数据发送开启心跳 |
- useWsMsg API说明
// 举例
const C = useWsMsg(A, B)
// 使用
const stopMsgListen = useWsMsg('xxx', (val) => {
console.log('ws数据:', val)
})
onUnmounted(stopMsgListen)
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
A | string | '' | 你需要监听哪个ws的数据获取 参考useInitWs里配置的url |
B | (val: T) => void | - | 数据监听回调 |
C | () => void | - | 停止监听 |
- useWsClose API说明
// 举例
const C = useWsClose(A, B)
// 使用
const stopWsCloseListen = useWsClose('xxx', () => {
console.log('ws关闭')
})
onUnmounted(stopWsCloseListen)
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
A | string | '' | 你需要监听哪个ws的关闭 参考useInitWs里配置的url |
B | (val: T) => void | - | 监听回调 |
C | () => void | - | 停止监听 |
- useWsError API说明
// 举例
const C = useWsError(A, B)
// 使用
const stopErrorListen = useWsError('xxx', () => {
console.log('ws异常')
})
onUnmounted(stopErrorListen)
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
A | string | '' | 你需要监听哪个ws的异常 参考useInitWs里配置的url |
B | (val: T) => void | - | 监听回调 |
C | () => void | - | 停止监听 |
import { TableColumnCtx, InputProps, SelectContext, cascaderProps, DatePickerProps, InputNumberProps, SelectV2Context, TimePickerDefaultProps, CascaderNode, CascaderValue, UploadProps, ElTooltipProps } from 'element-plus';
import { TimeSelectProps } from 'element-plus/es/components/time-select/src/time-select';
import { TreeComponentProps } from 'element-plus/es/components/tree/src/tree.type';
import { DefineComponent, ExtractPropTypes } from 'vue';
import { AxiosResultType } from '../axios/type';
/**
* @description 一些常用的ts工具函数
*/
export type GetArrItemType<T> = T extends (infer I)[] ? I : T; // 获取数组项的数据类型
export type DictChildType = GetArrItemType<AxiosResultType['getDictChild']>; // 字典类型
/**
* @description 表格组件的类型导出
*/
type OtherTableColumn<T> = {
prop: T extends Record<string, any> ? keyof T : string;
type: 'default' | 'selection' | 'index' | 'expand' | 'move',
slot: boolean;
show: any;
auth: string;
onlyAuth: boolean;
};
export type TableColumn<T = any> = Partial<
TableColumnCtx<T> & OtherTableColumn<T>
>[]; // 表格列的类型
export type TableColumnSlotType<T = any> = TableColumn<T>; // 表格列插槽的类型
export type TableRowType<T> = (T extends Array<infer I> ? I : T) | null; // 表格行的类型
export type TableEmitsType = 'info' | 'update' | 'del'; // 表格的操作类型
export type TableRefFuncType = {
// 表格的ref方法
clearSelection: () => void;
getSelectionRows: <T>() => TableRowType<T>[];
toggleRowSelection: <T>(row: TableRowType<T>, selected: boolean) => void;
toggleAllSelection: () => void;
toggleRowExpansion: <T>(row: TableRowType<T>, expanded: boolean) => void;
setCurrentRow: <T>(row: TableRowType<T>) => void;
clearSort: () => void;
doLayout: () => void;
clearFilter: (columnKey?: string[]) => void;
sort: (prop: string, order: string) => void;
scrollTo: (
options: number | ScrollToOptions,
yCoord?: number | undefined
) => void;
setScrollLeft: (left?: number | undefined) => void;
setScrollTop: (top?: number | undefined) => void;
};
/**
* @description 筛选区域的类型导出
*/
type SearchFilterDefaultType = {
id: string;
auth?: string; // 组件权限标识 需要配合父级的auth 不设置则默认展示
onlyAuth?: boolean; // 增加onlyAuth权限,在auth权限为显示的情况下,只有配置了onlyAuth也为显示,此筛选框才有权限显示
model: any; // 绑定的数据
show?: any; // 逻辑控制显示隐藏 显示时权限比auth低 隐藏时权限比auth高
};
type SearchFilter = { // 筛选区域的类型
'el-input': SearchFilterDefaultType & {
comName: 'el-input';
props?: Partial<InputProps>;
emits?: Partial<{
blur: (event: FocusEvent) => void;
focus: (event: FocusEvent) => void;
change: (value: string | number) => void;
input: (value: string | number) => void;
clear: () => void;
}>;
};
'el-select': SearchFilterDefaultType & {
comName: 'el-select';
children: {
comName: 'el-option';
data: any;
props?: Partial<{
value: string | number | boolean | object;
label: string | number;
disabled: boolean;
}>
};
props?: Partial<SelectContext['props']>;
emits?: Partial<{
change: (value: any) => void;
visibleChange: (visible: boolean) => void;
removeTag: (tagValue: any) => void;
clear: () => void;
blur: (event: FocusEvent) => void;
focus: (event: FocusEvent) => void;
}>
};
'el-cascader': SearchFilterDefaultType & {
comName: 'el-cascader';
props?: Partial<ExtractPropTypes<typeof cascaderProps> & {
options: any
}>;
emits?: Partial<{
change: (value: CascaderValue) => void;
expandChange: (value: CascaderValue) => void;
blur: (event: FocusEvent) => void;
focus: (event: FocusEvent) => void;
visibleChange: (value: boolean) => void;
removeTag: (value: CascaderNode['valueByOption']) => void
}>;
};
'el-date-picker': SearchFilterDefaultType & {
comName: 'el-date-picker';
props?: Partial<DatePickerProps>;
emits?: Partial<{
change: (value: any) => void;
blur: (e: FocusEvent) => void;
focus: (e: FocusEvent) => void;
calendarChange: (val: [Date, null | Date]) => void;
panelChange: (date: Date | [Date, Date], mode: 'month' | 'year', view?: string) => void;
visibleChange: (visibility: boolean) => void;
}>;
};
'el-input-number': SearchFilterDefaultType & {
comName: 'el-input-number';
props?: Partial<InputNumberProps>;
emits?: Partial<{
change: (currentValue: number | undefined, oldValue: number | undefined) => void;
blur: (event: FocusEvent) => void;
focus: (event: FocusEvent) => void;
}>;
};
'el-select-v2': SearchFilterDefaultType & {
comName: 'el-select-v2';
props?: Partial<SelectV2Context['props']>;
emits?: Partial<{
change: (val: any) => void;
visibleChange: (visible: boolean) => void;
removeTag: (tagValue: any) => void;
clear: () => void;
blur: (event: FocusEvent) => void;
focus: (event: FocusEvent) => void;
}>
};
'el-time-picker': SearchFilterDefaultType & {
comName: 'el-time-picker';
props?: Partial<TimePickerDefaultProps>;
emits?: Partial<{
change: (val: number | string | Date | [number, number] | [string, string] | [Date, Date]) => void;
blur: (e: FocusEvent) => void;
focus: (e: FocusEvent) => void;
visibleChange: (visibility: boolean) => void;
}>
};
'el-time-select': SearchFilterDefaultType & {
comName: 'el-time-select';
props?: Partial<TimeSelectProps>;
emits?: Partial<{
change: (value: string) => void;
blur: (e: FocusEvent) => void;
focus: (e: FocusEvent) => void;
}>;
};
'el-tree-select': SearchFilterDefaultType & {
comName: 'el-tree-select';
props?: Partial<SelectContext['props'] & TreeComponentProps>;
emits?: Partial<{
nodeClick: ((...args: any[]) => any);
nodeContextmenu: ((...args: any[]) => any);
checkChange: ((...args: any[]) => any);
check: ((...args: any[]) => any);
currentChange: ((...args: any[]) => any);
nodeExpand: ((...args: any[]) => any);
nodeCollapse: ((...args: any[]) => any);
nodeDragStart: ((...args: any[]) => any);
nodeDragEnter: ((...args: any[]) => any);
nodeDragLeave: ((...args: any[]) => any);
nodeDragOver: ((...args: any[]) => any);
nodeDragEnd: ((...args: any[]) => any);
nodeDrop: ((...args: any[]) => any);
change: (value: any) => void;
visibleChange: (visible: boolean) => void;
removeTag: (tagValue: any) => void;
clear: () => void;
blur: (event: FocusEvent) => void;
focus: (event: FocusEvent) => void;
}>
};
};
export type SearchType = SearchFilter[keyof SearchFilter];
/**
* @description 按钮组件类型导出
*/
type ClassType = 'primary' | 'success' | 'info' | 'warning' | 'danger';
type ButtonTypeDefault = {
default: { // 默认按钮
type?: 'default';
name: string;
icon?: DefineComponent;
auth: string;
func: (...args: any[]) => any;
class?: ClassType;
show?: any;
loading?: any;
developShow?: boolean;
};
children: { // 下拉按钮
type: 'select',
name: string;
class?: ClassType;
children: {
name: string;
icon?: DefineComponent;
auth: string;
func: (...args: any[]) => any;
show?: any;
loading?: any;
developShow?: boolean;
}[]
};
upload: { // 上传按钮
type: 'upload',
props: Partial<UploadProps>;
name: string;
auth: string;
class?: ClassType;
show?: any;
loading?: any;
developShow?: boolean;
icon?: DefineComponent;
};
tooltip: { // 提示按钮
type: 'tooltip',
name: string;
auth: string;
class?: ClassType;
show?: any;
loading?: any;
developShow?: boolean;
icon?: DefineComponent;
props: Partial<ElTooltipProps>;
func: (...args: any[]) => any;
}
}
export type ButtonType = ButtonTypeDefault[keyof ButtonTypeDefault];
/**
* @description 公共的配置类型导出
*/
export type ConfigType = Partial<{
localStorageKey: Partial<{
HDL_TOKEN: string; // token的标识 默认为HDL_TOKEN
HDL_USER: string; // 用户信息的标识 默认为HDL_USER
HDL_MENU: string; // 当前保存的菜单项
HDL_MENU_SN: string; // 浏览器获取菜单sn的标识 默认为HDL_MENU_SN
HDL_USER_NAME: string; // 用户名
HDL_PWD: string; // 密码
}>;
hdlLogin: Partial<{ // 登录组件的全局配置类型注解
loginSuccessRoute: string; // 登录成功后的默认路由
loginRoute: string; // 登录页的路由
refreshRouteName: string; // 刷新路由的名称
qkMenuType: string; // qiankun的菜单类型
}>;
hdlAxios: Partial<{ // axios请求配置
}>;
hdlTable: Partial<{ // 表格组件 用于表格的一些配置
operateColConfig: TableColumn; // 操作列配置
authVal: number; // 值为authVal的时候显示
onlyShowVal: boolean; // 值为onlyShowVal的时候显示
pageSizes: number[]; // 分页器每页显示个数
pageSize: number; // 分页器每页显示个数
popupPageSizes: number[]; // 弹窗分页器每页显示个数
popupPageSize: number; // 弹窗分页器每页显示个数
}>;
hdlMenus: Partial<{ // 菜单组件
width: number; // 菜单展开后的宽度
collapseWidth: number; // 菜单伸缩后的宽度
}>;
hdlSearch: Partial<{ // 筛选框组件
width: number; // 筛选框的默认宽度
}>;
hdlForm: Partial<{ // 表单组件
labelWidth: string; // 表单的label宽度
}>;
hdlTree: Partial<{ // 树组件
width: number; // 初始树宽度
minWidth: number; // 最小宽度
maxWidth: number; // 最大宽度
}>;
hdlWs: Partial<{
reconnectInter: number[]; // 重连时间间隔 默认为[1000, 3000, 10000, 30000, 60000]
}>;
}>