Vue+el-table实现不规则表格
小菜鸟在总结
·
比如:我们要实现下图这个表格
代码如下:
<template>
<div>
<el-table :data="tableData" :span-method="objectSpanMethod" border :header-cell-style="handerMethod">
<el-table-column align="center" prop="id" label=""></el-table-column>
<el-table-column align="center" prop="amount1" label="数据分类"></el-table-column>
<el-table-column align="center" prop="amount2" label="缴存业务"></el-table-column>
<el-table-column align="center" prop="amount3" label="提取业务"></el-table-column>
<el-table-column align="center" prop="amount4" label="贷款业务"></el-table-column>
<el-table-column align="center" label="业务办理合计">
<el-table-column align="center" label="业务办理合计" prop="amount5"></el-table-column>
<el-table-column align="center" label="" prop="amount6"></el-table-column>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
spanArr: [], // 用于存放每一行记录的合并数
tableData: [
{
id: '业务办理类业务统计量',
amount1: '线上服务量小计',
amount2: '1',
amount3: '2',
amount4: '3',
amount5: '4',
amount6: '4'
},
{
id: '业务办理类业务统计量',
amount1: '线上业务小计',
amount2: '1',
amount3: '2',
amount4: '3',
amount5: '4',
amount6: '4'
},
{
id: '业务办理类业务统计量',
amount1: '线下业务小计',
amount2: '1',
amount3: '2',
amount4: '3',
amount5: '4',
amount6: '4'
},
{
id: '业务办理类业务统计量',
amount1: '线上+线下',
amount2: '1',
amount3: '2',
amount4: '3',
amount5: '4',
amount6: '4'
},
{
id: '业务办理类业务统计量',
amount1: '线上占比',
amount2: '1',
amount3: '2',
amount4: '3',
amount5: '4',
amount6: '4'
},
{
id: '9大渠道服务总量统计',
amount1: '9大渠道服务总量统计',
amount2: '信息查询',
amount3: '信息发布',
amount4: '互动交流',
amount5: '业务办理',
amount6: '线上总计'
},
{
id: '9大渠道服务总量统计',
amount1: '9大渠道服务总量统计',
amount2: '01',
amount3: '02',
amount4: '03',
amount5: '04',
amount6: '05'
}
]
}
},
mounted() {
},
methods: {
// 隐藏表头
handerMethod({ rowIndex }) {
if (rowIndex === 1) {
// 这里为了是将第二列的表头隐藏,就形成了合并表头的效果
return { display: 'none' }
}
},
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
// 对第六、七行 进行合并
if (rowIndex === 5) {
if (columnIndex === 0) {
return [2, 2]
} else if (columnIndex === 1) {
return [0, 0]
}
}
// 对第一列 第二列 进行合并
if (columnIndex === 1 || columnIndex === 0) {
// 当 当前行与上一行内容相同时 返回0 0 意味消除
if (rowIndex > 0 && row[column.property] === this.tableData[rowIndex - 1][column.property]) {
return {
rowspan: 0,
colspan: 0
}
} else {
let rows = 1
// 反之 查询相同的内容有多少行 进行合并
for (let i = rowIndex; i < this.tableData.length - 1; i++) {
if (row[column.property] === this.tableData[i + 1][column.property]) {
rows++
}
}
// 返回相同内容的行数
return {
rowspan: rows,
colspan: 1
}
}
}
// 对第一、二、三、四、五行 进行合并
if (rowIndex === 0 || rowIndex === 1 || rowIndex === 2 || rowIndex === 3 || rowIndex === 4) {
// 处理合计,[1,2]表示合并1行2列,[0,0]表示改行不显示
if (columnIndex === 5) {
// 定位到5列的一、二、三、四、五行,告诉该单元格合并1行2列
return [1, 2]
} else if (columnIndex === 6) {
// 定位到6列的一、二、三、四、五行,告诉该单元格不显示
return [0, 0]
}
}
}
}
}
</script>
el-table 行合并
方法一:(直接使用)
<el-table
:data="tableData"
border
:span-method="objectSpanMethod"
style="width: 100%">
<el-table-column
prop="order"
label="序号"
align="center"
width="50">
</el-table-column>
<el-table-column
prop="name"
:label="'名称'"
align="center"
fixed="left"
width="70">
</el-table-column>
</el-table>
<script>
export default {
name: 'StationsStaTable',
data () {
return {
tableData: [],
},
methods: {
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
// 对第一列 第二列 进行合并
if (columnIndex === 1 || columnIndex === 0) {
// 当 当前行与上一行内容相同时 返回0 0 意味消除
if(rowIndex > 0 && row[column.property] === this.tableData[rowIndex - 1][column.property]){
return {
rowspan: 0,
colspan: 0
};
}else{
let rows = 1;
// 反之 查询相同的内容有多少行 进行合并
for(let i = rowIndex; i < this.tableData.length - 1; i++){
if (row[column.property] === this.tableData[i + 1][column.property]) {
rows++;
}
}
// 返回相同内容的行数
return {
rowspan: rows,
colspan: 1
};
}
}
}
}
方法二:(封装函数)
1、使用
导入js文件,并设置需要合并的列
//导入js文件(文件脚本内容在下文)
import {getRowspanMethod} from '@/hook/el-tables/use-span-method.js'
//调用函数并导出需要的合并列函数 注意需要根据
//data为查询到的数据
//['prop1', 'prop2', 'prop3'] 需要合并的列
const spanMethod=getRowspanMethod(data,['prop1', 'prop2', 'prop3'])
在vue页面模板中使用
<!--使用spanMethod方法-->
<el-table :data="data" height="100%" :span-method="spanMethod">
...
</el-table>
2、封装合并的方法
这个文件(use-span-method.js
)通过导出一个函数来提供给el-table的和并方法使用
/**
* 合并相同数据,导出合并列所需的方法(只适合el-table)
* @param {Object} data
* @param {Object} rowspanArray
*/
export function getRowspanMethod(data, rowspanArray) {
/**
* 要合并列的数据
*/
const rowspanNumObject = {};
//初始化 rowspanNumObject
rowspanArray.map(item => {
rowspanNumObject[item] = new Array(data.length).fill(1, 0, 1).fill(0, 1);
rowspanNumObject[`${item}-index`] = 0;
});
//计算相关的合并信息
for (let i = 1; i < data.length; i++) {
rowspanArray.map(key => {
const index = rowspanNumObject[`${key}-index`];
if (data[i][key] === data[i - 1][key]) {
rowspanNumObject[key][index]++;
} else {
rowspanNumObject[`${key}-index`] = i;
rowspanNumObject[key][i] = 1;
}
});
}
//提供合并的方法并导出
const spanMethod = function({ row, column, rowIndex, columnIndex }) {
if (rowspanArray.includes(column['property'])) {
const rowspan = rowspanNumObject[column['property']][rowIndex];
if (rowspan > 0) {
return { rowspan: rowspan, colspan: 1 }
}
return { rowspan: 0, colspan: 0 }
}
return { rowspan: 1, colspan: 1 }
};
return spanMethod;
}
3、vue2/3具体使用
// vue2
import {getRowspanMethod} from '@/hook/el-tables/use-span-method.js'
export default {
data(){
spanMethod:()=>{},
list:[],
},
methods:{
// 查询数据方法
getData(){
this.spanMethod=getRowspanMethod(this.list,['prop1', 'prop2', 'prop3'])
}
}
}
// vue3 setup
import {ref ,computed} from 'vue';
import {getRowspanMethod} from '@/hook/el-tables/use-span-method.js'
// 获取数据存放变量
let list=ref([]);
//实际根据业务灵活调整
const spanMethod=computed(()=>{
return getRowspanMethod(list.value,['prop1', 'prop2', 'prop3'])
})
// 查询数据方法
const getData=function(){
//查询到数据赋值
list.value=[];
}
el-table 列合并
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
// 处理合计,[1,2]表示合并2行2列,[0,0]表示改行不显示
if (rowIndex === 5) {
if (columnIndex === 0) {
// 定位到0列,告诉该单元格合并1行2列
return [1, 2]
} else if (columnIndex === 1) {
// 定位到1列,告诉该单元格不显示
return [0, 0]
}
}
}
el-table表头列合并
<el-table :data="tableData" :header-cell-style="handerMethod">
<el-table-column align="center" label="业务办理合计">
<el-table-column label="业务办理合计" prop="amount5"></el-table-column>
<el-table-column label="" prop="amount6"></el-table-column>
</el-table-column>
</el-table>
//隐藏表头
handerMethod({rowIndex}){
if (rowIndex === 1) {
//这里为了是将第二列的表头隐藏,就形成了合并表头的效果
return {display: 'none'}
}
},
<el-table-column label="业务办理合计" prop="amount5"></el-table-column>
<el-table-column label="" prop="amount6"></el-table-column>
</el-table-column>
```js
//隐藏表头
handerMethod({rowIndex}){
if (rowIndex === 1) {
//这里为了是将第二列的表头隐藏,就形成了合并表头的效果
return {display: 'none'}
}
},
el-table自定义合计
效果图如下:代码实现:
<template>
<div style='height: 800px;width: 100%;background: #fff;'>
<el-table ref="table" border :data="tableData" :span-method="objectSpanMethod" stripe class="table-class" show-summary :summary-method="getNodeSummaries" highlight-current-row>
<el-table-column type="index" label="序号" width="50"></el-table-column>
<el-table-column prop="name" label="名字" align="center" />
<el-table-column prop="sex" label="性别" width="120" align="center" />
<el-table-column prop="tiZh" label="体重" width="120" align="center" />
<el-table-column prop="num1" label="爬山次数" width="120" align="center" />
<el-table-column prop="num2" label="游泳次数" width="120" align="center" />
<el-table-column prop="num3" label="健身次数" width="120" align="center" />
</el-table>
</div>
</template>
<script>
// import { ref } from 'vue'
export default {
name: 'aaaa',
components: {},
props: {},
data() {
return {
tableData: [
{
name: '张三',
sex: '男',
tiZh: 120,
num1: 1000,
num2: 2000,
num3: 3000
},{
name: '张四',
sex: '女',
tiZh: 120,
num1: 1000,
num2: 2000,
num3: 3000
},
],
}
},
computed: {},
mounted() {},
methods: {
objectSpanMethod() {
this.$nextTick(x => {
if (this.$refs.table.$el) {
var current = this.$refs.table.$el
.querySelector(".el-table__footer-wrapper")
.querySelector(".el-table__footer");
var cell = current.rows[0].cells;
cell[0].style.display = "none";
cell[1].style.display = "none";
cell[2].style.display = "none";
cell[3].classList.remove('is-left')
cell[3].colSpan = "4";
}
})
},
getNodeSummaries(param) {
const { columns, data } = param;
const sums = [];
let arr = [ 'num1', 'num2', 'num3']
columns.forEach((column, index) => {
if (index === 3) {
sums[index] = "合计";
return;
}
if (arr.some(x => column.property === x)) {
sums[index] = 0;
data.map((item) => {
console.log(item)
let num = item[column.property];
// num = num ? parseFloat(num.replace(/,/gi, "")) : 0;
sums[index] = this.accAdd(sums[index], num);
});
} else {
sums[index] = "";
}
});
return sums;
},
accAdd(arg1, arg2) {
let r1, r2, m;
try {
r1 = arg1.toString().split(".")[1].length;
} catch (e) {
r1 = 0;
}
try {
r2 = arg2.toString().split(".")[1].length;
} catch (e) {
r2 = 0;
}
m = Math.pow(10, Math.max(r1, r2));
return ((arg1 * m + arg2 * m) / m).toFixed(2);
},
}
}
</script>
<style lang='scss' scoped>
.table-class{
width: 50%;
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
更多推荐
已为社区贡献6条内容
所有评论(0)