vue 自定义的通用的表格组件(使用div)
做项目的时候由于传统的table及elementUI的el-table的tr和td没办法设置间距,满足不了UI提供的设计稿,为了还原,自己封装了该组件
该表格组件的特点
- 表头排序功能:支持点击表头进行升序、降序排序,并显示相应的排序图标。
- 复选框功能:可以在表格中为每一行数据添加复选框,并支持全选和取消全选操作。
- 图表展示:支持在表格中展示图表数据,提供相应的图表显示和交互功能。
- 文件上传功能:对于特定的列,支持文件上传和编辑操作,并可以显示上传进度和状态。
- 按钮操作:支持在表格中添加按钮并绑定相应的点击事件,实现自定义的操作功能(可以动态控制按钮的显示和禁用状态)。
- 支持单元格内容的格式化显示
- 行点击事件:支持点击表格某一行触发相应的事件处理。
- 包含了滚动条联动的功能,右侧侧固定列和表格内容的联动滚动
该表格组件的介绍
封装组件具体用了vue哪些指令
-
条件渲染
- 使用了 v-if 指令来根据条件判断是否渲染整个表格容器。
样式类绑定:
- 使用了 v-if 指令来根据条件判断是否渲染整个表格容器。
-
样式类绑定
- 使用了 :class 绑定动态的样式类。。
-
表头渲染:
- 使用了 v-for 指令循环渲染表头的每一列。
- 对每一列进行了样式设定,并且设置了点击事件处理函数。
-
表格内容渲染:
- 使用了 v-for 指令循环渲染表格的每一行和每一列。
- 对每个单元格进行了样式设定,并且设置了点击事件处理函数。
-
固定列:
- 在表格右侧实现了固定列的功能,并根据条件判断是否渲染固定列的内容。
-
事件处理:
- 使用了 @click 绑定点击事件处理函数。
- 使用了 @change 监听复选框的变化事件。
-
插槽:
- 使用了 slot 标签定义插槽,用于插入其他组件或内容。
表头部分
这部分代码负责渲染表格的表头结构,包括表头的各个列以及相关的操作按钮、排序功能等
<div class="common-table-header">
......
</div>
表格内容
这部分代码负责根据数据 data 动态渲染表格的行和列内容,包括每一行中的单元格内容、操作按钮、上传编辑功能等。
<div v-for="(row, index) in data">
......
</div>
类名介绍
- common-table-body — 表格内容的盒子(除表头外)高度需固定(固定原因:表格滚动条)
- common-table-body-wrapper — 表格内容的盒子(除表头外)高度自适应
- common-table-row — 每一行的类名
固定列部分
<div class="common-table-box-fixed">
......
</div>
传参介绍
- data — 表格显示的数据
- columns — 表格列字段
- 传参格式
- label对应value
- label2对应value1 — 这块后加的,value2被占用所以没对上可自行更改
- label3对应value3
- 传参格式
[{
label: '表头名称',
value: "对应列内容的字段名",
width: '表格列的宽度 --- 此处都是转化为vw以便自适应',
paddingLeft: '每一列的左内边距默认都为20',
paddingRight: '每一列的右内边距默认都为20',
isSort: '是否是索引',
position: "文字是位置-- center:居中;center-left:居左",
valueFormatter: "单元格内容的格式化显示---方法 --- 解析value",
valueFormatter1: "单元格内容的格式化显示---方法--- 解析value1",
valueFormatter3: "单元格内容的格式化显示---方法 --- 解析value3 ",
isHidden: '隐藏列',
isDate: '日期格式 --- 日期有特殊样式显示',
label2: '表头名称 --- 表格显示过多时一列支持显示1-3个字段,举例:表头名为姓名/性别/电话',
value1: '对应列内容的字段名 --- 表格显示过多时一列支持显示1-3个字段,举例:姓名/性别/电话竖着展示',
label3: '表头名称 --- 表格显示过多时一列支持显示1-3个字段,举例:表头名为姓名/性别/电话',
value3: '对应列内容的字段名 --- 表格显示过多时一列支持显示1-3个字段,举例:姓名/性别/电话竖着展示',
isTooltip: 是否超出显示提示框 --- value内容,
isTooltip1: 是否超出显示提示框 --- value1内容,
isTooltip2: 是否超出显示提示框 --- value3内容,
value2: '表格值显示。一般显示名称后value2用来拼接到value后的',
wordColor: '表格内容样色,默认为黑色,当该值为true则为灰色',
isCommonProgress: '显示进度条',
wrap: '通常用在操作列,按钮是否可以换行',
isButton: '代表渲染按钮',
buttonList: '按钮集合',
fontColorIsBlue: '文字颜色变为蓝色',
isbadge: '内容右上角显示的标记此处为数量',
isProgressVal: '进度,这块显示两行,上边为具体值,下册为百分比进度',
unit: '表格内容如果需要单位且不用valueFormatter,可直接使用该值进行传递',
isEcharts: '需要绘制echarts',
isImg: '代表需要展示图片',
question: '表头显示提示框解释该字段表格含义',
isClick: '表格可以点击需结合callback进行使用,只有点击每一列生效',
callback: '方法,点击表格某行后执行',
bgFormatter: '方法,根据某个值给表格行添加背景'
}]
- 举例
tableColumns = [
{
label: "序号",
value: "sort",
width: this.windowWidth <= 1024 ? 70 * 2 : 78 * 2,
paddingLeft: this.windowWidth <= 1024 ? 10 * 2 : 20 * 2,
paddingRight: this.windowWidth <= 1024 ? 10 * 2 : 20 * 2,
isSort: true,
position: "center"
},
{
label: "创建日期",
value: "createTime",
isDate: true,
width: this.windowWidth <= 1024 ? 140 * 2 : 148 * 2,
position1: "center-left",
valueFormatter: this.valueDateFormat,
paddingLeft: 0,
paddingRight: 0,
isHidden: this.windowWidth <= 1024
},
{
label: "类型",
value: "type",
width: this.windowWidth <= 1024 ? 85 * 2 : 107 * 2,
position: "center",
valueFormatter: this.valueSourceFormat,
paddingLeft: this.windowWidth <= 1024 ? 10 * 2 : 20 * 2,
paddingRight: this.windowWidth <= 1024 ? 10 * 2 : 20 * 2
},
];
- isJump
- 点击表格任意行及任意位置都能触发
- isChoose
- 支持选中某一行
- needJudgeChooseStatus
- false-任意选;true-需要满足某些条件才能被选
- buttonList
- 固定操作列按钮集合
- fixedWidth
- 固定操作列宽
- fixedLabel
- 固定操作表头的label
- rowId
- 选中某一行时判断是否重复选择的属性key
- isScroll
- 是否支持滚动表格后才加载某些内容
- checkDisabledLabel
- 表格多选框是否禁用要判断的属性key
- titleCheck
- 表格表头多选框的绑定值
- titleChekcDisabled
- 表格表头多选框是否禁用
- chooseNumber
- 选中表格行最多支持的数量
- chooseTooltip
- 选中表格行等于支持的数量后再选的提示
方法介绍
- handleClickSort(handleSortDown,handleSortUp)
- 表格的列头点击时触发排序操作,调用 $emit 方法来触发排序事件,并将排序方式和排序字段作为参数传递给父组件,供其进行相应的处理。
- handleChangeCheck
- 调用 $emit 方法触发勾选事件,将当前行的row作为参数传递给父组件
- handleChangeCheckAll
- 代表全选当前页 - 调用 $emit 方法触发勾选事件传递给父组件
- progressoFormat
- 用于格式化进度条的显示文本。该方法接收两个参数:percentage 表示进度百分比,status 表示进度状态
- handleAvatarSuccess
上传文件调用的方法
- res-表示上传成功的响应对象
- index-表示索引值
- row 表示行信息。
- beforeAvatarUpload
上传文件判断文件类型和大小,根据条件决定是否压缩文件,并将结果返回给上传组件。同时,也会触发上传事件,并将索引值传递给父组件。
- getFontColorIsBlue(getFontColorIsBlue1,getFontColorIsBlue2)
- 判断是否给表格某列的添加类名,对文字颜色进行改变
- getColumnValue(getColumnValue1,getColumnValue3)
- 用来格式化内容
- getColumnBg
- 判断是否给该行添加背景类名
- getColumnClass(getColumnClass1,getColumnClass2)
- 判断是否给该行添加文字类名
- getWidth
- 设置每一列宽度
- getPadding
- 设置每一列内间距
- getButtonDisabled
- 判断按钮是否禁用
- getButtonDisplay
- 判断按钮是否隐藏显示
- handleJudgeOperate
- 判断该列是否隐藏显示
- handleListenerScroll
- 表格滚动事件
- combinedScroll
- 右侧侧固定列和表格内容的联动滚动
- handleClickRow
- 点击某一行
- clearChooseData
- 清除选中的内容
完整代码
commonTable.vue
<template>
<div
class="h-common-table-container"
v-if="data.length > 0"
>
<div
class="common-table-box"
>
<div class="common-table-box-wrapper">
<div class="common-table-header">
<div
v-for="(column, index) in columns"
:key="index"
:style="[
{ width: getWidth(column.width, column) },
{ textAlign: column.position || 'left' },
{
paddingLeft:
column.position != 'center' && getPadding(column.paddingLeft)
},
{
paddingRight:
column.position == 'right' && getPadding(column.paddingRight)
},
{
display: column.isCheckBox ? 'flex' : '',
justifyContent: column.isCheckBox ? 'center' : '',
alignItems: column.isCheckBox ? 'center' : ''
}
]"
:class="[
{ 'no-padding': column.position == 'center' },
{
'padding-right': column.isButton && column.position == 'right'
},
{ 'column-flex': column.sort },
{ 'column-date': column.isDate }
]"
v-show="handelJudgeFixed(column) && !column.isHidden"
@click.stop="handleClickSort(column)"
>
<el-checkbox
v-if="column.isCheckBox"
:disabled="titleChekcDisabled"
v-model="titleCheck"
@change="handleChangeCheckAll($event, columns)"
></el-checkbox>
<span class="column-label" v-if="!column.isCheckBox">{
{
column.label
}}</span>
<span class="column-label-another" v-if="column.label2">{
{
column.label2
}}</span>
<div class="sort-box" v-if="column.sort">
<span @click.stop="handleSortUp(column)"
><img
src="@/assets/img/up.png"
alt=""
v-if="sortValue != 1"/><img
src="@/assets/img/upChoose.png"
alt=""
v-if="sortValue == 1"
/></span>
<span @click.stop="handleSortDown(column)"
><img
src="@/assets/img/down.png"
alt=""
v-if="sortValue != 2"/><img
src="