element ui table 表格自定义边框样式,边框颜色。合并单元格,合并行。element ui table表格行转列 电脑版发表于:2024/10/15 17:30 设计图: <img src="https://img.tnblog.net/arcimg/aojiancc2/295120fd5e434d3b8d8e128889b9047f.png" style="width:666px;height:auto;"> [TOC] ### 具体的代码和样式(表格没有加上合并行的) 关于自定义边框样式都加了星号的 ``` <template> <div class="app-container"> <el-table :data="tableData" :header-cell-style="headerCellStyle" :row-style="rowStyle" :border="true" style="width: 100%"> <el-table-column prop="date" label="日期" width="180"> </el-table-column> <el-table-column prop="name" label="姓名" width="180"> </el-table-column> <el-table-column prop="address" label="地址"> </el-table-column> </el-table> </div> </template> <script> export default { // 组件名字 name: "AnalyseTrendByMonth", // 组件参数 props: { percentage: { type: Number, default: 0, }, title: { type: String, default: "", }, }, data() { return { columnsConfg: [ { label: "", prop: "describePlatform", width: "178px", paddingLeft: "35px", textAlign: "left", }, ], rowdata: [], headerCellStyle: { background: "rgba(29, 123, 189, 1)", height: "39px", color: "#fff", // border: '1px solid tan', // 注意如果想要降低表头高度,需要设置一下padding,不然它默认的padding有点大,你高度设置得在小它也有一定的高度 paddingTop: "0px", paddingBottom: "0px", }, rowStyle: { color: "#fff", height: "39px", //background: 'rgba(8, 32, 68, 0.7)', // 新版本皮肤表格行颜色 background: "rgba(8, 65, 120, 0.4)", // marginBottom: "10px", opacity: "0.8", paddingTop: "10px", paddingBottom: "10px", }, tableData: [ { date: "2016-05-02", name: "王小虎", address: "上海市普陀区金沙江路 1518 弄", }, { date: "2016-05-04", name: "王小虎", address: "上海市普陀区金沙江路 1517 弄", }, { date: "2016-05-01", name: "王小虎", address: "上海市普陀区金沙江路 1519 弄", }, { date: "2016-05-03", name: "王小虎", address: "上海市普陀区金沙江路 1516 弄", }, ], }; }, mounted() { }, // 组件方法 methods: { }, }; </script> <style scoped="scoped" lang="scss"> .app-container { padding-top: 5px; padding-bottom: 10px; } </style> <!-- 表格样式 --> <style scoped="scoped" lang="scss"> ::v-deep.el-table--border::after, ::v-deep .el-table--group::after, ::v-deep .el-table::before { content: ""; position: absolute; background-color: #ebeef5; z-index: 1; display: none; } // ************这里设置边框样式 ************ // 这里是整个表格外面一圈的边框样式 ::v-deep .el-table--border{ border: 1px solid rgba(255, 255, 255, 0.2); border-right: none; border-bottom: none; } ::v-deep .el-table--group{ border: 1px solid rgba(255, 255, 255, 0.2); border-right: none; border-bottom: none; } // element ui table 鼠标移动高亮颜色 ::v-deep .el-table tbody tr:hover > td { background: #23aaac !important; } /* 表格内背景颜色 */ ::v-deep .el-table th, ::v-deep .el-table tr, ::v-deep .el-table td { background-color: transparent; } // 设置行间距 ::v-deep .el-table__body { border-collapse: separate !important; // 设置这里居然会影响边框线的对齐 // border-spacing: 0px 3px !important; } // ************这里设置边框样式 ************ ::v-deep .el-table--border .el-table__cell { border-bottom: 1px solid rgba(255, 255, 255, 0.2); border-right: 1px solid rgba(255, 255, 255, 0.2); } // ************这里设置边框样式 ************ ::v-deep .el-table th.el-table__cell.is-leaf { border-bottom: 1px solid rgba(255, 255, 255, 0.2) } // 这句代码加了鼠标指上去变色就显示不出来 ::v-deep.el-table--enable-row-transition .el-table__body td.el-table__cell { background-color: transparent !important; } ::v-deep.el-table td.el-table__cell div.cell { background-color: transparent !important; } ::v-deep .el-table { background-color: transparent !important; } ::v-deep .el-table__row { background-color: transparent; } /* 去除底部白线 */ .el-table::before { background-color: transparent; } .pageWrapper { margin: 10px auto; text-align: center; padding-bottom: 15px; } // --------------------隐藏table gutter列和内容区右侧的空白 start ::v-deep .el-table th.gutter { display: none; width: 0; } ::v-deep .el-table colgroup col[name="gutter"] { display: none; width: 0; } // 这个样式不加的话内容哪里会缺一点,估计是因为滚动条哪里缺的没有补上 ::v-deep .el-table__body { width: 100% !important; } // --------------------隐藏table gutter列和内容区右侧的空白 end </style> ``` ### 加上合并行之后的 ``` <template> <div class="app-container"> <el-table :data="tableData" :span-method="courseSpan" :header-cell-style="headerCellStyle" :row-style="rowStyle" :border="true" style="width: 100%"> <el-table-column prop="date" label="日期" width="180"> </el-table-column> <el-table-column prop="name" label="姓名" width="180"> </el-table-column> <el-table-column prop="address" label="地址"> </el-table-column> </el-table> </div> </template> <script> export default { // 组件名字 name: "AnalyseTrendByMonth", // 组件参数 props: { percentage: { type: Number, default: 0, }, title: { type: String, default: "", }, }, data() { return { columnsConfg: [ { label: "", prop: "describePlatform", width: "178px", paddingLeft: "35px", textAlign: "left", }, ], rowdata: [], headerCellStyle: { background: "rgba(29, 123, 189, 1)", height: "39px", color: "#fff", // border: '1px solid tan', // 注意如果想要降低表头高度,需要设置一下padding,不然它默认的padding有点大,你高度设置得在小它也有一定的高度 paddingTop: "0px", paddingBottom: "0px", }, rowStyle: { color: "#fff", height: "39px", //background: 'rgba(8, 32, 68, 0.7)', // 新版本皮肤表格行颜色 background: "rgba(8, 65, 120, 0.4)", // marginBottom: "10px", opacity: "0.8", paddingTop: "10px", paddingBottom: "10px", }, tableData: [ { date: "2016-05-02", name: "王小虎", address: "上海市普陀区金沙江路 1518 弄", }, { date: "2016-05-02", name: "王大虎", address: "上海市普陀区金沙江路 3213 弄", }, { date: "2016-05-04", name: "张晓白", address: "上海市普陀区金沙江路 1517 弄", }, { date: "2016-05-04", name: "陈木惟", address: "上海市普陀区金沙江路 6666 弄", }, { date: "2016-05-01", name: "柏树枝", address: "上海市普陀区金沙江路 1519 弄", }, { date: "2016-05-03", name: "杨华锋", address: "上海市普陀区金沙江路 1516 弄", }, ], }; }, mounted() { this.initCourseSpanArr(this.tableData) }, // 组件方法 methods: { // 处理合并数据 initCourseSpanArr(data) { const spanArray = []; for (var i = 0; i < data.length; i++) { if (i === 0) { spanArray.push(1); this.pos = 0; } else { // 判断当前元素与上一个元素是否相同。这里是判断需要合并的字段 if (data[i].date === data[i - 1].date) { spanArray[this.pos] += 1; spanArray.push(0); } else { spanArray.push(1); this.pos = i; } } } this.courseSpanArry = spanArray; }, courseSpan({rowIndex, columnIndex }) { if (columnIndex === 0) { const _row = this.courseSpanArry[rowIndex]; const _col = _row > 0 ? 1 : 0; return { rowspan: _row, colspan: _col, }; } }, }, }; </script> <style scoped="scoped" lang="scss"> .app-container { padding-top: 5px; padding-bottom: 10px; } </style> <!-- 表格样式 --> <style scoped="scoped" lang="scss"> ::v-deep.el-table--border::after, ::v-deep .el-table--group::after, ::v-deep .el-table::before { content: ""; position: absolute; background-color: #ebeef5; z-index: 1; display: none; } // ************这里设置边框样式 ************ // 这里是整个表格外面一圈的边框样式 ::v-deep .el-table--border { border: 1px solid rgba(255, 255, 255, 0.2); border-right: none; border-bottom: none; } ::v-deep .el-table--group { border: 1px solid rgba(255, 255, 255, 0.2); border-right: none; border-bottom: none; } // element ui table 鼠标移动高亮颜色 ::v-deep .el-table tbody tr:hover > td { background: #23aaac !important; } /* 表格内背景颜色 */ ::v-deep .el-table th, ::v-deep .el-table tr, ::v-deep .el-table td { background-color: transparent; } // 设置行间距 ::v-deep .el-table__body { border-collapse: separate !important; // 设置这里居然会影响边框线的对齐 // border-spacing: 0px 3px !important; } // ************这里设置边框样式 ************ ::v-deep .el-table--border .el-table__cell { border-bottom: 1px solid rgba(255, 255, 255, 0.2); border-right: 1px solid rgba(255, 255, 255, 0.2); } // ************这里设置边框样式 ************ ::v-deep .el-table th.el-table__cell.is-leaf { border-bottom: 1px solid rgba(255, 255, 255, 0.2); } // 这句代码加了鼠标指上去变色就显示不出来 ::v-deep.el-table--enable-row-transition .el-table__body td.el-table__cell { background-color: transparent !important; } ::v-deep.el-table td.el-table__cell div.cell { background-color: transparent !important; } ::v-deep .el-table { background-color: transparent !important; } ::v-deep .el-table__row { background-color: transparent; } /* 去除底部白线 */ .el-table::before { background-color: transparent; } .pageWrapper { margin: 10px auto; text-align: center; padding-bottom: 15px; } // --------------------隐藏table gutter列和内容区右侧的空白 start ::v-deep .el-table th.gutter { display: none; width: 0; } ::v-deep .el-table colgroup col[name="gutter"] { display: none; width: 0; } // 这个样式不加的话内容哪里会缺一点,估计是因为滚动条哪里缺的没有补上 ::v-deep .el-table__body { width: 100% !important; } // --------------------隐藏table gutter列和内容区右侧的空白 end </style> ``` ##### 合并单元格的代码就是js这点 ``` mounted() { this.initCourseSpanArr(this.tableData) }, // 组件方法 methods: { // 处理合并数据 initCourseSpanArr(data) { const spanArray = []; for (var i = 0; i < data.length; i++) { if (i === 0) { spanArray.push(1); this.pos = 0; } else { // 判断当前元素与上一个元素是否相同。这里是判断需要合并的字段 if (data[i].date === data[i - 1].date) { spanArray[this.pos] += 1; spanArray.push(0); } else { spanArray.push(1); this.pos = i; } } } this.courseSpanArry = spanArray; }, courseSpan({rowIndex, columnIndex }) { if (columnIndex === 0) { const _row = this.courseSpanArry[rowIndex]; const _col = _row > 0 ? 1 : 0; return { rowspan: _row, colspan: _col, }; } }, }, ``` 还有就是表格上方要加上这句: ``` <el-table :span-method="courseSpan"> ``` ### 对接真实的接口,加上行转列的效果 单独的示例可以参考一下这篇文章,这里边的数据没有对接真是接口逻辑要简单一些:https://www.tnblog.net/xiuxin3/article/details/8482 **接口返回的数据源是这个样子:** 有评估,实验,产教的数据接口回来,这里只展示了评估的数据接口作为示例: ``` { "code": 0, "data": [ { "systemName": null, "year": 2024, "month": 9, "quantity": 0, "completPr": 0.2164, "planCompletePr": 0.8455172413793103448275862069 }, { "systemName": null, "year": 2024, "month": 10, "quantity": 0, "completPr": 0.3224, "planCompletePr": 0.4787902592301649646504320503 }, { "systemName": null, "year": 2024, "month": 11, "quantity": 0, "completPr": 0.0, "planCompletePr": 0.0 }, { "systemName": null, "year": 2024, "month": 12, "quantity": 0, "completPr": 0.0, "planCompletePr": 0.0 }, { "systemName": null, "year": 2025, "month": 1, "quantity": 0, "completPr": 0.0, "planCompletePr": 0.0 } ], "success": true, } ``` **接口出来的数据源要先处理成这个样子的,这样行专列好处理一点:** ``` const rawData = [ { "type": "评估", "month": 9, "CompleteType": "目标达成率", "CompleteValue": 0.2164 }, { "type": "评估", "month": 10, "CompleteType": "整体完成率", "CompleteValue": 0.7164 }, { "type": "审计", "month": 9, "CompleteType": "目标达成率", "CompleteValue": 0.6164 }, { "type": "审计", "month": 10, "CompleteType": "整体完成率", "CompleteValue": 0.5164 }, ]; ``` **整体代码如下:** this.$sysconfig.evaluate_name_short = "评估" this.$sysconfig.labroom_name_short = "实验" this.$sysconfig.prod_name_short = "产教" ``` <template> <div class="app-container"> <el-table :data="tableData" :span-method="courseSpan" :header-cell-style="headerCellStyle" :row-style="rowStyle" :border="true" style="width: 100%"> <el-table-column prop="type" label="系统" width="180" align="center"> </el-table-column> <el-table-column prop="indicator" label="类型" width="180" align="center"> </el-table-column> <el-table-column v-for="(month, key) in monthMapValues" align="center" :key="key" :label="month" :prop="month" :formatter="formatPercentage" /> </el-table> </div> </template> <script> export default { // 组件名字 name: "AnalyseTrendByMonth", // 组件参数 props: { percentage: { type: Number, default: 0, }, title: { type: String, default: "", }, }, data() { return { columnsConfg: [ { label: "", prop: "describePlatform", width: "178px", paddingLeft: "35px", textAlign: "left", }, ], rowdata: [], headerCellStyle: { background: "rgba(29, 123, 189, 1)", height: "39px", color: "#fff", // border: '1px solid tan', // 注意如果想要降低表头高度,需要设置一下padding,不然它默认的padding有点大,你高度设置得在小它也有一定的高度 paddingTop: "0px", paddingBottom: "0px", }, rowStyle: { color: "#fff", height: "39px", //background: 'rgba(8, 32, 68, 0.7)', // 新版本皮肤表格行颜色 background: "rgba(8, 65, 120, 0.4)", // marginBottom: "10px", opacity: "0.8", paddingTop: "10px", paddingBottom: "10px", }, monthTableData: [], tableData: [], monthMapValues: ["9月", "10月"], monthMap: {}, monthResultCount: 0, }; }, mounted() { this.monthResultCount = 0; this.getSysUseMonthReport(); }, watch: { monthResultCount(newVal) { // 三个平台的数据都回来了在去处理行专列合并单元格等 if (newVal === 3) { // console.log("三个平台的数据都回来了...") // 这里可以进行一个排序,方便自己控制数据列的展示 this.monthTableData = this.monthTableData.slice().sort((a, b) => a.sort - b.sort); let transformTableData = this.transformData(this.monthTableData, this.monthMap); this.tableData = transformTableData; this.initCourseSpanArr(transformTableData); } }, }, // 组件方法 methods: { formatPercentage(row, column, cellValue) { // console.log("看看返回值", cellValue); // 这个方法可以用于格式化百分比,但我们已经在transformData中完成了格式化 // 所以这里可以直接返回cellValue,或者根据需要进行进一步处理 return cellValue; }, // 行专列方法,把行中的月份转化为方法 transformData: function (data, monthMap) { const result = []; const types = [...new Set(data.map((item) => item.type))]; const completeTypes = [...new Set(data.map((item) => item.completType))]; types.forEach((type) => { completeTypes.forEach((completeType) => { const row = { type: type, indicator: completeType, ...Object.keys(monthMap).reduce((acc, month) => { const value = data.find((item) => item.type === type && item.completType === completeType && item.month === parseInt(month, 10))?.completValue; let returnValue = "0%"; if (value >= 0) { returnValue = (value * 100).toFixed(2); } else { returnValue = "-"; } return { ...acc, [monthMap[month]]: returnValue }; // return { ...acc, [monthMap[month]]: value ? (value * 100).toFixed(2) + "%" : "-" }; }, {}), }; result.push(row); }); }); return result; }, // 系统月使用情况 getSysUseMonthReport: async function () { let stId = await this.$getStId(); let my = this; let mCount = 7; const currentDate = new Date(); const currentYear = currentDate.getFullYear(); let currentMonth = currentDate.getMonth(); this.monthMapValues = []; this.monthTableData = []; this.monthResultCount = 0; let monthMap = {}; for (let index = currentMonth; index < currentMonth + 7; index++) { let calYear = currentYear; let calMonth = index; // 说明应该是下一年开始了 if (index > 12) { calYear = calYear + 1; calMonth = index - 12; } monthMap[calMonth] = calMonth + "月"; // 给动态列名提供数据 this.monthMapValues.push(calMonth + "月"); // console.log("看看年月", calYear, calMonth); } this.monthMap = monthMap; // console.log("看看月转化对象", monthMap); // 评估完成情况 this.$http.get("/evaluation/api/TeacherReportCurriculum/XX", { SchoolTermID: stId, monthCount: mCount, IncludeAll: this.includeAll }).then((res) => { // console.log("评估月使用情况", res.data); // 每月都要显示一条数据,其实用行转列做逻辑应该简单点 for (let index = currentMonth; index < currentMonth + 7; index++) { let calYear = currentYear; let calMonth = index; // 说明应该是下一年开始了 if (index > 12) { calYear = calYear + 1; calMonth = index - 12; } // console.log("看看年月", calYear, calMonth); let findData = res.data.find((a) => a.month == calMonth && a.year == calYear); my.monthTableData.push({ sort: 1, type: my.$sysconfig.evaluate_name_short, year: calYear, month: calMonth, completType: "目标达成率", completValue: findData.planCompletePr, }); my.monthTableData.push({ completType: "整体完成率", sort: 2, year: calYear, type: my.$sysconfig.evaluate_name_short, month: findData.month, completValue: findData.completPr, }); } my.monthResultCount = my.monthResultCount + 1; // let transformTableData = this.transformData(my.monthTableData, monthMap); // this.tableData = transformTableData // this.initCourseSpanArr(transformTableData) // console.log("看看表格组装出来的数据呢",my.monthTableData) // console.log("看看转化出来后的表格", this.tableData); }); // 实验完成情况 this.$http.get("/labroom/api/Report/XX", { stdetailID: stId, monthCount: mCount, IncludeAll: this.includeAll }).then((res) => { // console.log("实验月使用情况", res.data); // 每月都要显示一条数据,其实用行转列做逻辑应该简单点 for (let index = currentMonth; index < currentMonth + 7; index++) { let calYear = currentYear; let calMonth = index; // 说明应该是下一年开始了 if (index > 12) { calYear = calYear + 1; calMonth = index - 12; } let findData = res.data.find((a) => a.month == calMonth && a.year == calYear); my.monthTableData.push({ sort: 3, completType: "目标达成率", type: my.$sysconfig.labroom_name_short, year: calYear, month: calMonth, completValue: findData.goalAchievementPr, }); my.monthTableData.push({ sort: 4, completType: "整体完成率", type: my.$sysconfig.labroom_name_short, month: findData.month, year: calYear, completValue: findData.mustDoCompletPr, }); } my.monthResultCount = my.monthResultCount + 1; }); // 产教使用情况 this.$http.get("/prodedu/api/v2/Report/XX", { stdetailID: stId, monthCount: mCount, includeAll: this.includeAll }).then((res) => { // console.log("产教月使用情况", res.data); // 每月都要显示一条数据,其实用行转列做逻辑应该简单点 for (let index = currentMonth; index < currentMonth + 7; index++) { let calYear = currentYear; let calMonth = index; if (index > 12) { calYear = calYear + 1; calMonth = index - 12; } let findData = res.data.find((a) => a.month == calMonth && a.year == calYear); my.monthTableData.push({ sort: 5, completType: "目标达成率", type: my.$sysconfig.prod_name_short, year: calYear, month: calMonth, completValue: findData.monthCper, }); my.monthTableData.push({ sort: 6, completType: "整体完成率", type: my.$sysconfig.prod_name_short, month: findData.month, year: calYear, completValue: findData.completPr, }); } my.monthResultCount = my.monthResultCount + 1; }); }, // 处理合并数据 initCourseSpanArr(data) { const spanArray = []; for (var i = 0; i < data.length; i++) { if (i === 0) { spanArray.push(1); this.pos = 0; } else { // 判断当前元素与上一个元素是否相同。这里是判断需要合并的字段 if (data[i].type === data[i - 1].type) { spanArray[this.pos] += 1; spanArray.push(0); } else { spanArray.push(1); this.pos = i; } } } this.courseSpanArry = spanArray; }, courseSpan({ rowIndex, columnIndex }) { if (columnIndex === 0) { const _row = this.courseSpanArry[rowIndex]; const _col = _row > 0 ? 1 : 0; return { rowspan: _row, colspan: _col, }; } }, }, }; </script> <style scoped="scoped" lang="scss"> .app-container { padding-top: 5px; padding-bottom: 10px; } </style> <!-- 表格样式 --> <style scoped="scoped" lang="scss"> ::v-deep.el-table--border::after, ::v-deep .el-table--group::after, ::v-deep .el-table::before { content: ""; position: absolute; background-color: #ebeef5; z-index: 1; display: none; } // ************这里设置边框样式 ************ // 这里是整个表格外面一圈的边框样式 ::v-deep .el-table--border { border: 1px solid rgba(255, 255, 255, 0.2); border-right: none; border-bottom: none; } ::v-deep .el-table--group { border: 1px solid rgba(255, 255, 255, 0.2); border-right: none; border-bottom: none; } // element ui table 鼠标移动高亮颜色 ::v-deep .el-table tbody tr:hover > td { background: #23aaac !important; } /* 表格内背景颜色 */ ::v-deep .el-table th, ::v-deep .el-table tr, ::v-deep .el-table td { background-color: transparent; } // 设置行间距 ::v-deep .el-table__body { border-collapse: separate !important; // 设置这里居然会影响边框线的对齐 // border-spacing: 0px 3px !important; } // ************这里设置边框样式 ************ ::v-deep .el-table--border .el-table__cell { border-bottom: 1px solid rgba(255, 255, 255, 0.2); border-right: 1px solid rgba(255, 255, 255, 0.2); } // ************这里设置边框样式 ************ ::v-deep .el-table th.el-table__cell.is-leaf { border-bottom: 1px solid rgba(255, 255, 255, 0.2); } // 这句代码加了鼠标指上去变色就显示不出来 ::v-deep.el-table--enable-row-transition .el-table__body td.el-table__cell { background-color: transparent !important; } ::v-deep.el-table td.el-table__cell div.cell { background-color: transparent !important; } ::v-deep .el-table { background-color: transparent !important; } ::v-deep .el-table__row { background-color: transparent; } /* 去除底部白线 */ .el-table::before { background-color: transparent; } .pageWrapper { margin: 10px auto; text-align: center; padding-bottom: 15px; } // --------------------隐藏table gutter列和内容区右侧的空白 start ::v-deep .el-table th.gutter { display: none; width: 0; } ::v-deep .el-table colgroup col[name="gutter"] { display: none; width: 0; } // 这个样式不加的话内容哪里会缺一点,估计是因为滚动条哪里缺的没有补上 ::v-deep .el-table__body { width: 100% !important; } // --------------------隐藏table gutter列和内容区右侧的空白 end </style> ``` ### element ui table 自定义样式其他参考 https://www.tnblog.net/aojiancc2/article/details/8061 https://www.tnblog.net/notebook/article/details/8469 https://www.tnblog.net/aojiancc2/article/details/8111