前言:
使用 Element UI 表格组件时,如果你希望将每两行数据关联起来并且展示为一个整合的视觉效果,实现行之间的关联线(例如,表示父子关系、下载回传标识)可以考虑自定义表格的列内容配合 template 和 slot 插槽来自定义一些样式和结构。
思路:
1、创建基础表格
-
使用 <el-table> 和 <el-table-column> 来构建基础表格
2、定义连接线列
-
新建一列用于绘制连接线,使用自定义插槽(template + slot)来实现
3、利用奇偶行的定义进行分开
-
在插槽中,通过遍历行数据,动态计算每行的索引奇偶性(index + 1)% 2
-
确保样式适应奇偶行规律的变化 根据奇偶行判断 动态展示上下不同的样式
4、通过 CSS 类名控制连接线样式
-
通过 CSS 自定义连接线的样式(如虚实线、颜色等)
效果:
表格行左侧 下载回传 关联线

完整代码(插槽连接线样式实现方法):
<template>
<div class="sendEmail">
<m-editable
class="m-editable"
:data="passTableData"
height="200"
style="height: 200px"
:border="false"
:columns="tableColumns"
:header-cell-style="rowClass"
>
<template slot="default-iamge" slot-scope="scope" style="height: 100%;">
<div v-if="(scope.$index + 1) % 2" class="associationBorder">
<div class="associationBorderMax assoc"></div>
</div>
<div v-else class="associationBorder">
<div class="associationBorderMax associa"></div>
</div>
</template>
<template slot="default-fileName" slot-scope="scope">
<m-table-cell
type="text"
:value = "{name: scope.row.fileName, weight: 'bold'}",
:value2 = "{name: scope.row.filePath, weight: '400'}"
>
</m-table-cell>
</template>
<template slot="default-btnGroup" slot-scope="scope" >
<span class="download iconStyle" v-if="scope.row.passSign === ''">
<el-upload
action="string"
:show-file-list="false"
:accept="imageLimit"
:on-success="handleAvatarSuccess"
:before-upload="beforeUpload"
:http-request="(m) => toRequestPassback(m, scope.$index)"
fit="scale-down"
>
回传附件
</el-upload>
<div style="margin-left: 10px;" @click.stop="handleRemove(scope.$index)">
<m-iconfont
classify="m-pc-dsmc iconfont"
icon="m-pc-dsmc_shanchu"
size="14"
></m-iconfont>
</div>
</span>
<span
class="download"
@click.stop="onDownload(scope.row)"
v-else
>
下载附件
</span>
</template>
</m-editable>
</div>
</template>
export default {
layout: '',
name: '',
data() {
emailTableData: [],
passTableData: []
}
methods: {
getDetail() {
this.$axios({
method: 'get',
url: ``,
})
.then((res) => {
this.emailTableData = res.data.fileList
const pass = [];
this.emailTableData.forEach((item) => {
pass.push(item);
const passBack = {
fileName: '(请回传关联文件)',
filePath: '',
fileSize: '',
fileType: '',
passSign: ''
}
pass.push(passBack);
})
this.passTableData = pass
})
},
rowClass({row,column, rowIndex, columnIndex }) {
if (rowIndex === 0 && columnIndex === 0) {
return {background:'#ffffff !important'}; //不用这种写法不生效
}
return null;
},
}
}
<style lang="less" type="text/less" scoped>
.sendEmail{
.m-elitable{
min-height: 200px;
.associationBorder {
height: 40px;
width: 20px;
position: relative;
.associationBorderMax {
box-sizing: border-box;
height: 20px;
width: 20px;
border: 1px solid #000;
border-right: 0px;
position: absolute;
}
.assoc {
bottom: 0;
border-bottom: 0px;
}
.associa {
top: 0;
border-top: 0px;
}
}
}
}
</style>


