// 子组件
<template>
<!-- // 表格合并 -->
<div class="sub-table">
<div class="table-body-div table-body-div-no-border">
<el-table
:data="tableData"
:span-method="objectSpanMethod"
:cell-class-name="tableRowClassName"
border
style="width: 100%; margin-top: 20px;"
>
<template v-for="item in tableHeader">
<el-table-column
:key="`index-${item.prop}`"
:prop="item.prop"
:label="item.label"
:width="item.width"
>
<template slot-scope="scope">
<div style="display: flex;display: -webkit-flex;display: -ms-flex;-webkit-justify-content: center;-ms-justify-content: center;justify-content: center;flex-wrap: wrap;-webkit-flex-wrap: wrap;-ms-flex-wrap: wrap;">
<slot name="tableBody" :value="scope.row" :prop="item.prop" :item="item" />
</div>
</template>
</el-table-column>
</template>
<el-table-column
v-if="isUseBar"
:fixed="barFixed"
:label="extraName"
:width="barWidth"
:align="barAlign ? barAlign : 'left'"
>
<template slot-scope="scope">
<div style="display: flex;display: -webkit-flex;display: -ms-flex;-webkit-justify-content: center;-ms-justify-content: center;justify-content: center;flex-wrap: wrap;-webkit-flex-wrap: wrap;-ms-flex-wrap: wrap;">
<slot name="tableColumn" :value="scope.row" />
</div>
</template>
</el-table-column>
</el-table>
</div>
</div>
</template>
<script>
export default {
name: 'TableView',
props: {
// 这个是处理合并的列和行的--以下是结构
// {
// name: 0, // 需要处理的列数,第几列
// value: 'measureTime' // 需要处理合并的字段
// }
megreArray: {
type: Array,
default: () => {
return []
},
require: true
},
// 表头
tableHeader: {
type: Array,
default: () => {
return []
}
},
// 数据
tableDatas: {
type: Array,
default: () => {
return []
}
},
// 这个是排序字段
compareKey: {
type: String,
default: '',
require: true
},
barWidth: {
type: String,
default: '140'
},
barFixed: {
type: String,
default: 'right'
},
barAlign: {
type: String,
default: 'center'
},
extraName: {
type: String,
default: function() {
return '操作'
}
},
isUseBar: {
type: Boolean,
default: true
}
},
data() {
return {
orderIndexArr: [],
lengthArray: [],
hoverOrderArr: [],
tableData: [],
rowIndex: '-1'
}
},
watch: {
tableDatas(val) {
this.tableData = val
this.getOrderNumber(this.tableDatas, this.megreArray)
}
},
created() {
// 开始处理
if (this.tableDatas) {
this.tableData = this.tableDatas
this.getOrderNumber(this.tableDatas, this.megreArray)
}
},
methods: {
// 获取相同编号的数组
getOrderNumber(array, megree) {
array = JSON.parse(JSON.stringify(array))
this.orderIndexArr = []
if (megree) {
if (megree.length > 0) {
// 先取第一个算出第一个合并的东西
megree.forEach((svalue, aindex) => {
if (aindex === 0) {
const orderObj = {
name: svalue.name,
value: []
}
let temp = array
temp = this.fn(temp, megree[0].value)
temp.forEach(svaluea => {
if (svaluea.data) {
// 排序
svaluea.data = svaluea.data.sort(this.compare(this.compareKey))
}
})
// 处理之后temp处理成散数组
const tempArrayList = []
temp.forEach(svaluec => {
if (svaluec.data) {
svaluec.data.forEach(gvalue => {
tempArrayList.push(gvalue)
})
}
})
tempArrayList.forEach((item, index) => {
item.rowIndex = index
if (orderObj[item[svalue.value]]) {
orderObj[item[svalue.value]].push(index)
} else {
orderObj[item[svalue.value]] = []
orderObj[item[svalue.value]].push(index)
}
})
// 将数组长度大于1的值 存储到this.orderIndexArr(也就是需要合并的项)
Object.keys(orderObj).forEach((key) => {
if (orderObj[key].length > 1 && key !== 'value') {
orderObj.value.push(orderObj[key])
}
})
this.orderIndexArr.push(orderObj)
} else if (aindex > 0) {
const orderObj = {
name: svalue.name,
value: []
}
// 如果超过两个,先对数组根据第一个megree来合并相同,并排序
let temp = array
temp = this.fn(temp, megree[0].value)
temp.forEach((svaluea, indexa) => {
if (svaluea.data) {
// 排序
svaluea.data = svaluea.data.sort(this.compare(this.compareKey))
// 处理为tableData的每一个megree对应的key值加上index。
svaluea.data.forEach(gvalue => {
gvalue[svalue.value] = gvalue[svalue.value] + indexa
})
}
})
// 处理之后temp处理成散数组
const tempArrayList = []
temp.forEach(svaluec => {
if (svaluec.data) {
svaluec.data.forEach(gvalue => {
tempArrayList.push(gvalue)
})
}
})
// 在进行合并处理
tempArrayList.forEach((item, index) => {
item.rowIndex = index
if (orderObj[item[svalue.value]]) {
orderObj[item[svalue.value]].push(index)
} else {
orderObj[item[svalue.value]] = []
orderObj[item[svalue.value]].push(index)
}
})
// 将数组长度大于1的值 存储到this.orderIndexArr(也就是需要合并的项)
Object.keys(orderObj).forEach((key) => {
if (orderObj[key].length > 1 && key !== 'value') {
orderObj.value.push(orderObj[key])
}
})
this.orderIndexArr.push(orderObj)
}
})
}
}
},
compare(property) {
return function(a, b) {
var value1 = a[property]
var value2 = b[property]
// return value1.localeCompare(value2) // 这是字符串比较
return value1 - value2
}
},
/**
* 先去重,后合并
* 1、源数据去重
* 2、把去重后的数据和源数据中相同name的数据合并citys
*/
fn(data, keyValue) {
const keySet = new Set(data.map(item => item[keyValue]))
return Array.from(keySet).map(v => {
return {
key: v,
data: data.filter(item => item[keyValue] === v)
}
})
},
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
for (let i = 0; i < this.orderIndexArr.length; i += 1) {
if (columnIndex === this.orderIndexArr[i].name) {
for (let s = 0; s < this.orderIndexArr[i].value.length; s += 1) {
const element = this.orderIndexArr[i].value[s]
for (let j = 0; j < element.length; j += 1) {
const item = element[j]
if (rowIndex === item) {
if (j === 0) {
return {
rowspan: element.length,
colspan: 1
}
}
if (j !== 0) {
return {
rowspan: 0,
colspan: 0
}
}
}
}
}
}
}
},
// 算指定位数的求和
qh(array, length) {
let sum = 0
for (let i = 0; i < length; i++) {
sum += array[i]
}
return sum
},
tableRowClassName({ row, rowIndex }) {
const arr = this.hoverOrderArr
for (let i = 0; i < arr.length; i += 1) {
if (rowIndex === arr[i]) {
return 'hovered-row'
}
}
},
// 鼠标移入样式
cellMouseEnter(row) {
this.rowIndex = row.rowIndex
this.hoverOrderArr = []
this.orderIndexArr.forEach((element) => {
if (element['value'] && element.name === 0) {
element['value'].forEach(dvalue => {
if (dvalue.indexOf(this.rowIndex) >= 0) {
this.hoverOrderArr = dvalue
}
})
}
})
},
// 鼠标离开
cellMouseLeave() {
this.rowIndex = '-1'
this.hoverOrderArr = []
}
}
}
</script>
<style>
.el-table .hovered-row {
background: #f5f7fa;
}
.sub-table .el-image__error, .sub-table img{
width:60px;
height:60px;
line-height: 60px;
}
</style>
<style scoped lang="scss">
.sub-table{
width:100%;
height:auto;
text-align: left;
}
</style>
// 父组件调用
<template>
<div>
<daily-record-hb-table
:megre-array="megreArray"
:table-header="dailyFoodListTable"
:table-datas="dataValue"
:compare-key="compareKey"
:is-use-bar="isUseBar"
style="margin-top:20px"
>
<template v-slot:tableBody="tableBody">
<p>
{{ tableBody.value[tableBody.prop] }}
</p>
</template>
</daily-record-hb-table>
</div>
</template>
<script>
import sHbTable from '@/components/DataTable/tableMerge'
export default {
components: {
'daily-record-hb-table': sHbTable
},
data(){
megreArray: [
{
name: 0, // 需要处理的列数
value: 'measureTime' // 需要处理的字段
},
{
name: 1,
value: 'MEALNameHb'
}
],
compareKey: 'MEAL',
isUseBar: false,
dailyFoodListTable: [],
dataValue:[]
}
}
</script>
【js-vue】基于element-ui表格封装合并行和列,可直接使用
最新推荐文章于 2024-07-03 18:35:16 发布
这是一个关于如何在Vue组件中实现表格数据的合并和排序处理的示例。组件接收包括合并列配置、表头信息、数据源等参数,并通过自定义方法`getOrderNumber`进行数据处理和排序。同时,提供了`tableRowClassName`方法用于实现行的鼠标悬停样式。父组件通过插槽`tableBody`来自定义表格内容。
摘要由CSDN通过智能技术生成