slb_public_components
v0.0.82
Published
This is a Vue3 + ts + ELement-Plus pulic components.
Downloads
320
Readme
slb_public_components
介绍
Vue3 +ts+ELement-Plus 公用组件库
依赖的库有 vue3,ELement-Plus,windicss,wangeditor,请在系统中自行安装
配置文件(.env.xxxxx),依赖vite
需要在环境变量配置中配置以下字段
VITE_APP_CONFIG = {
// 翻页器配置
"page":{
"current":1,
"size":10
},
// 页码
"pageSizes": [5,10, 20, 30, 40, 50],
// 七牛云上传配置
"qiniuyun":{
// 图床地址
"url":"https://xxx.xx.com",
"token": {
// 后端token校验请求头字段映射
"requestTokenName":"token",
// 前端获取本地token的请求头字段映射
"getTokenName": "token"
},
// 获取七牛云上传token接口请求地址
"reqUrl":"/xxxxx/xxxx/get",
// 请求方法,默认为POST
"method":"POST",
// 请求参数
"body":{},
// 自定义请求头配置
"headers":{
"service":"/xxx/xx/get"
}
},
// 是否滚动加载,不写就是正常分页
"scrollRequest":{
// 是否滚动加载
"isScroll": false,
// 滚动加载获取list最后一条数据的翻页参数名称, 如果没有则使用page 的页码翻页
"endParameterName": "id",
// 后端接受最后一条数据的参数名称
"requestParameterName": "lastId"
},
// 分页组件位置
'paginationPosition': '' // 'start' | 'center' | 'end'
// 是否隐藏单页不显示分页
"hideOnSinglePage": true,
// 是否使用首页total作为总条数/因后端大数据量时每页返回totle也很耗时故配合增加此配置
"isHomePageTotal": true
}
MergeFormTable 组件参数及用法
用于带有搜索和表格的页面,是 PublicTable 组件和 SearchForm 组件的包装组件
<MergeFormTable
:table-data="tablData" // form搜索菜单的配置
:form-data="formData" // table表格的配置
:call-back="getList" // 获取列表的方法
v-model="reqParams" // 必填,搜索栏绑定的mode
:exportExcelApi="apixxx" // 选填,页面会多一个导出Excel的按钮,
@exportExce="exportFn" // 导出Excel按钮的返回事件,返回值为exportExcelApi请求的结果
@selectionChange="selectionChange" //表格多选:当选择项发生变化时会触发该事件
>
<template #customBtn> // customBtn插槽插入到搜索栏下方的自定义内容
<el-button type="primary" @click="$router.push('/system/version/add')">添加版本类型</el-button>
</template>
<template #exportExcelBtn> //与导出Excel按钮同级,用于添加按钮权限
<el-button type="success">导出Excel</el-button>
</template>
<template #control="{ row }">
<el-button
type="primary"
@click="$router.push({ path: '/system/version/add', query: { id: row.id } })"
>
编辑版本
</el-button>
</template>
</MergeFormTable>
//一般情况下可以搭配获取列表的hook一起使用,下方代码就能创建一个只有显示,搜索功能的表格页面
import { useGetList } from 'slb_public_components';
// 见下方SearchForm配置
const formData: ISearchFormConfig = [
...
];
// 见下方PublicTable配置,如果没有特殊显示需求只用配置config
// 其余配置也可以添加,但是会覆盖hook中默认的配置
const tableConfig: ItableDataConfigProps = {
config: [
...
]
};
const getListParam = {
requestFn: getRecommendGoodsList // 获取列表的api
tableConfig: tableConfig, //table的配置
obtainField: 'records',//返回结果参数获取字段,默认"$$$data",获取后端返回全部数据
immediately: false,//是否立即执行函数
//自定义回调方法,常用于处理后端返回特殊数据
//如果涉及多层级数据应当返回 { list: AnyObject[];total: number }
resultProcessing(v:AnyObject){
// 只有一层时,直接返回数组
// return v.records
// 指定数据列表和分页数据
return {
list: v.page.records,
total: v.page.total
};
},
// 翻页字段顺序不变依次为:当前页数,显示条目个数,总条目数 默认从环境变量VITE_APP_CONFIG读取
page:{
"current": 1,
"size": 10,
"total":0
},
/**
* 请求参数初始值,通常用于设置时间搜索默认值
* ```ts
* // 列子:
* const example:ISearchFormConfig = {
type: 'dateTime',
prop: 'delivery',
label: '发货时间',
placeholder: ['发货开始时间', '发货结束时间'],
config: ['deliveryStartTime', 'deliveryEndTime']
};
const { getList, queryParams, tableData } = useGetList({
queryParamsAdditional:{
deliveryStartTime:"2024-12-15 08:12:56",
deliveryEndTime:"2024-12-15 08:12:56",
}
});
*
* ```
*/
queryParamsAdditional:{}
};
/**获取列表hook,注意hook内部已进行onBeforeMount初始化请求过一次列表了,具体使用方法使用时查看useGetList()函数注释*/
const { getList, queryParams, tableData } = useGetList(getListParam);
使用 MergeFormTable 组件时是否使用 useGetList 这个 hook 看实际项目中的情况并不是必须的只是为了减少代码量 主要差别在于:
- 需要将 tableConfig 配置书写完整
- 需要自定义 queryParams 对象属性
- 需要自定义获取列表函数
PublicTable 组件参数及用法
<PublicTable
:tableData="tableData"
@handlePageChange="handlePageChange" //点击分页回调
@SelectionChange="SelectionChange" //表格多选结果回调
>
<template #name="{ row, column, $index }">
<el-button>{{ row.name }}</el-button>
</template>
</PublicTable>
const tableData:ItableDataProps = {
loading: false, //加载动画
attrs: {} // table 属性方法,
defaultConfig: {
//是否开启多选
selection: true,
//是否开启数字展示
index: true
// 表头和内容都居中展示
allAlignCenter: true;
// 自动计算表头宽度
isAutoHeaderWidth: true;
// 返回值用来决定这一行的 CheckBox 是否可以勾选
selectable: (row: AnyObject, index: number) => boolean;
},
config: [
{
prop: 'name', //表格对应字段,如果type为slot时也是插槽名
label: '日期', //表格对应字段中文描述
width: '130', //表格单个格子宽度
type: 'slot' // 插槽类型,在html标签中自定义样式
ShowFn: () => false // 是否显示该列
},
{
prop: 'status',
label: '活动状态',
type: 'switch', // 使用开关
options: {
activeValue: 0, //自定义参数值 打开状态
inactiveValue: 1 //自定义参数值 关闭状态
},
//开关切换回调方法
callBack(v: any) {
console.log(v);
}
},
{
prop: 'address',
label: '地址',
// 用于表格的回显
formatter(val: any) {
return val.province + val.city + val.district + val.address;
}
},
// 排序
{
type: 'money',
prop: 'money',
sort: {
method: (a, b) => a.money - b.money
},
label: '金额'
},
{
prop: 'url',
label: '图片',
type: 'img' //使用图片
},
{
prop: 'time',
label: '开始时间',
type: 'time' // 自动处理显示时间为YYYY-MM-DD HH:mm:ss
},
{
prop: 'money',
label: '现金',
type: 'money' // 后端返回金额单位为分,处理数据为元进行显示
},
{
prop: 'id',
label: 'id', // 不做任何处理直接显示后端返回数据
},
// 多级表头
{
type: 'column',
label: '伙人',
children: [
{
label: '钱',
type: 'column',
children: [
{
prop: 'address',
label: '分',
type: 'slot'
},
{
prop: 'name',
label: '源'
},
{
type: 'column',
label: '金额',
children: [
{
type: 'img',
prop: 'url',
label: '开盘价'
},
{
type: 'money',
prop: 'money',
label: '价'
},
{
type: 'slot',
prop: 'name',
label: '源来的'
}
]
}
]
},
{
prop: 'city',
label: '动态'
}
]
}
],
// 为table树形结构时才设置tree
tree:{
defaultExpandAll: true, // 是否默认展开
treeProps: { children: 'children', hasChildren: 'hasChildren' }, // 字段设置
lazy: false, // 是否异步展开子级
rowKey:"id", // key的键
load: ()=> {}, // 异步方法
},
page: {
page_index: 1, //当前分页页码
page_size: 10, //当前分页展示条数
total: 0 //总数
},
//后端返回的数据
data: []
};
SearchForm 组件参数及用法
<SearchForm :form-data="data" :v-model=defaultValue>
<template #d>
<el-button>{{ 11111 }}</el-button>
</template>
</SearchForm>
// 表单mode用于请求的对象,这里面的默值对应dateTime中的config的字段名就行能实现默认时间
const defaultValue = ref({createStartTime: '时间',createEndTime: '时间'})
const data:ISearchFormConfig = [
/** input输入框 */
{
prop: 'ab', //对应mode中字段
label: '兴趣:', //表单label,标题
type: 'ipt', //组件类型
placeholder: '请输入兴趣',// 支持placeholder的el组件
labelWidth:80 //label宽度
},
/** 条件显示 */
{
prop: 'abc',
label: '兴趣:',
type: 'ipt',
placeholder: '请输入兴趣',
labelWidth:80,
showFn: (v: any) => { // 条件显示这个组件v其实就是defaultValue
return v.ab ? false : true
}
},
/** 日期范围选择器 */
// dateTime类型比较特殊
// 1,如果后端接受的数据为一个字段时:数据格式['时间xx','时间xx']可以直接填入prop,此时prop就能直接使用,用于后端请求数据
// 2,如果后端需要接受的参数是两个属性,就需要在config中填入两个属性名第一个是开始时间,第二个为结束时间,
{
prop: 'e',
label: '日期:',
type: 'dateTime',
placeholder: ['开始日期', '结束日期'] //自定义placeholder
config: ['createStartTime','createEndTime'] // 当需要将数组解析为两个字段时的参数
},
/** 日期选择器 */
{
prop: 'eqq',
label: '日期:',
type: 'date',
placeholder: '选择日期'
},
/** 级连选择器 */
{
prop: 'eerr',
label: '日期:',
type: 'cascader',
placeholder: '选择日期',
cascaderData: treeData,
cascaderOptions: {
showAllLevels: false, //仅显示最后一级,false为显示
multiple: false, //开启多选
checkStrictly: true, //选择任意一级选项
emitPath: false, //选择是否为数组格式
value: "val", //自定义对象的某个属性值
label: "name", //自定义对象的某个字段
children: "chilieMenu" //自定义对象子级名称
}
},
/** 下拉框用法一 */
{
prop: 'c',
label: '选择:',
type: 'select',
placeholder: '请选择',
/**下拉框参数,{自定义:自定义} 需要自己设置,需要添加到下面config与数组中保持一致 */
options: [
{
val: '1',
name: 'Option1'
},
{
val: '2',
name: 'Option2'
},
{
val: '3',
name: 'Option3'
},
{
val: '4',
name: 'Option4'
}
],
config: ['val', 'name']
},
/** 下拉框用法二 */
{
prop: 'c',
label: '选择:',
type: 'select',
placeholder: '请选择',
/** 返回一个异步函数 */
options:async ()=>([]),
/**下拉框参数,{自定义:自定义} 需要自己设置,需要添加到下面config与数组中保持一致 */
config: ['val', 'name']
},
/** 级联选择器 */
{
type: 'cascader',
prop: 'deliveryType3',
label: '配送方式3',
placeholder: '请选择配送方式',
options: async ()=>([]) || [{id:123, name: '张三',children:[id:23, name: '张三',]}],
cascaderOptions: {
showAllLevels: true, // 输入框中是否显示选中值的完整路径
multiple: true, // 开启多选
checkStrictly: true, // 选择任意一级选项
emitPath: true, // 选择是否为数组格式
value: 'id', // 自定义对象的某个属性值
label: 'name', // 自定义对象的某个字段
children: 'children' // 自定义对象子级名称
}
},
/**自定义组件 */
{
prop: 'd',
label: 'xx'
type: 'slot' // 为插槽时prop就是插槽名,可以自定义样式
},
//icon组件名称,可自定义(参考:https://element-plus.org/zh-CN/component/icon.html#icon-collection)
{
type: 'search',
icon: 'Search',
/** 参数值为整个f/orm表单输入值 */
event: (v) => {
console.log(v);
}
},
{
type: 'reset',
icon: 'Refresh',
event: (v) => {}
}
];
SForm 组件参数及用法
<SForm ref="formRef" :options="options" label-width="100px" v-mode="formData">
<template #slot>
<el-button size="small" type="primary">上传</el-button>
</template>
</SForm>
// 组件配置
Attributes: {
options: [] //菜单配置必传
allTextNullReplace: string // 默认为空字符串,当为text组件时值为空时,组件会自动将所有空值替换为空字符串,
modelValue: []// form组件的mode,必传
isDetails: false //是否在详情页展示为true时,可通过h插槽定义标题,f插槽定义底部按钮
formWidth: 100% // 控制整个表单宽度
resetSaveFormItemValue: false // 重置表单时是否保留mode的初始值,
EliminateUnnecessaryParameter: false // 提交时是否剔除掉和options配置中prop无关的属性,为true只保留options中配置的prop属性
isDeepCopy: false // 是否开启深拷贝,为true时,mode的初始值会进行深拷贝,防止mode被修改
isDynamicChildren: false // // 是否根据modelValue改变时重新渲染子元素
// 注意: el-from本身拥有的属性也可直接配置参考https://element-plus.gitee.io/zh-CN/component/form.html#form-attributes
}
// 内置有默认的七牛云上传方法,如果项目里不是七牛云或者通过后端上传的请自定义方法
import { useQiniuUpload } from 'slb_public_components';
const formData = ref<AnyObject>({});
// 注意: 当涉及到动态修改配置时请使用ref或者计算属性
let options: ISFormConfig = [
// 正常组件使用
{
type: 'input', // 组件根据element-plus组件去掉el
label: '用户名', // lable名称
prop: 'username', // 组件双向绑定的值,输入后在formData中获取值
textNullReplace: '--' // text组件时候为空时的显示内容
rules: [ // 校验方法
{ required: true, message: '用户名不能为空', trigger: 'blur' },
{ min: 2, max: 6, message: '用户名长度为2-6位', trigger: 'blur' },
],
attrs: { // 这里可以配置element-plus中所有对应组件的Attributes
clearable: true
},
showFn(val: any) { // 传入方法通过条件进行显隐
return val.role ? false : true
}
},
// select组件使用方法1
{
type: 'select',
placeholder: '请选择',
label: '职位',
prop: 'role',
attrs: {
style: {
width: '100%',
},
},
rules: [
{ required: true, message: '职位不能为空', trigger: 'change' }
],
childrenConfig: {
type: 'option',
props: {
label: 'label',
value: 'value';
}
}
children: [
{
label: '经理',
value: '1'
},
{
label: '总裁',
value: '2'
},
{
label: 'CEO',
value: '3'
},
]
},
// select组件使用方法2
{
type: 'select',
placeholder: '请选择',
label: '职位',
prop: 'role',
attrs: {
style: {
width: '100%',
},
},
rules: [
{ required: true, message: '职位不能为空', trigger: 'change' }
],
children: [
{
type: 'option',
label: '经理',
value: '1'
},
{
type: 'option',
label: '总裁',
value: '2'
},
{
type: 'option',
label: 'CEO',
value: '3'
},
]
},
// select组件使用方法3
{
type: 'select',
placeholder: '请选择',
label: '职位',
prop: 'role',
attrs: {
style: {
width: '100%',
},
},
rules: [
{ required: true, message: '职位不能为空', trigger: 'change' }
],
childrenConfig: {
type: 'option',
props: {
label: 'label',
value: 'value';
}
}
children: async ()=>([]) //返回一个异步函数
},
// checkbox-group
{
type: 'checkbox-group',
value: [],
prop: 'like',
label: '爱好',
rules: [
{ required: true, message: '爱好不能为空', trigger: 'change' }
],
children: [
{
type: 'checkbox',
label: '篮球',
value: '1',
},
{
type: 'checkbox',
label: '足球',
value: '2',
},
]
},
// radio-group
{
type: 'radio-group',
prop: 'terminalType',
label: '终端类型:',
children: [
{
type: 'radio',
value: 'ANDROID',
label: '安卓'
},
{
type: 'radio',
value: 'IOS',
label: '苹果'
}
],
rules: [{ required: true, message: '请选择终端类型', trigger: 'change' }]
},
// upload 自定义的uploadImage组件attrs配置见uploadImage组件
{
type: 'upload',
label: '上传',
prop: 'avatar',
rules: [
{ required: true, message: '图片不能为空', trigger: 'change' }
],
attrs: {
...
},
uploadFn: useQiniuUpload().qiniuUplaod // 上传图片组件必须传入上传方法
},
// 文字显示
{
type: 'text',
label: '文字显示',
prop: 'text',
}
// 富文本
{
type: 'editor',
label: '富文本',
prop: 'editor',
uploadFn: useQiniuUpload().qiniuUplaod // 富文本组件必须传入上传方法
}
// 自定义组件,当使用特殊样式和该组件不支持的组件时使用插槽插入
{
type: 'slot',
label: '自定义组件',
prop: 'slot',
}
]
// 通过ref 可以获取到表单的resetFields: 重置方法和validate()返回拷贝后的值: 校验方法然后进行后续操作
const formRef = ref<SFomInstance>();
ImageUpload 组件
<ImageUpload v-model="formData.url" :limit="1" :uploadFn: useQiniuUpload().qiniuUplaod ></ImageUpload>
// 内置有默认的七牛云上传方法,如果项目里不是七牛云或者通过后端上传的请自定义方法
import { useQiniuUpload } from 'slb_public_components';
// 组件配置
Attributes: {
uploadFn: useQiniuUpload().qiniuUplaod; // 必传,或者自定义方法
modelValue: xx; //接受上传图片返回的值,必传
multiple: false; // 是否多选,也就是一次性选取多张同时上传
limit: 1; //数量限制,当为0时只用作图片预览
fileSize: 5; // 图片大小
fileType: ['png', 'jpg', 'jpeg']; // 可接收的文件格式
isShowTip: true; // 是否显示下方提示信息
targetRatio: [1, 1]; // 上传图片的宽高比
}
// emit 事件
const emit = defineEmits({
'update:modelValue': (v: string[] | string) => typeof v === 'string' || Array.isArray(v),
'uploadSuccess': null,
'removeIndex': (index: number) => typeof index === 'number'
});