效果图:
1. 【合并行】
通过给table
传入span-method
方法可以实现合并行或列,方法的参数是一个对象,里面包含当前行row
、当前列column
、当前行号rowIndex
、当前列号columnIndex
四个属性。该函数可以返回一个包含两个元素的数组,第一个元素代表rowspan
,第二个元素代表colspan
。 也可以返回一个键名为rowspan
和colspan
的对象。
:span-method="objectSpanMethod"
spanNumArr: [], // 合并行数
posNum: [], // 记录位置
created() {
// 获取合并行行数
this.getSpanNumArr(this.tableData)
},
methods: {
// 获取合并行的行数
getSpanNumArr(data) {
this.spanNumArr = []
this.posNum = 0
for (var i = 0; i < data.length; i++) {
if (i === 0) {
this.spanNumArr.push(1)
this.posNum = 0
} else {
if (data[i].name === data[i - 1].name) {
this.spanNumArr[this.posNum] += 1
this.spanNumArr.push(0)
} else {
this.spanNumArr.push(1)
this.posNum = i
}
}
}
},
// 设置合并行
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
if (column.property == 'name') {
const _row = this.spanNumArr[rowIndex]
const _col = _row > 0 ? 1 : 0 // 0 值是为了去除错位
return {
rowspan: _row,
colspan: _col
}
}
},
}
2.【筛选功能】
在列中设置filters
filter-method
属性即可开启该列的筛选,filters 是一个数组,filter-method
是一个方法,它用于决定某些数据是否显示,会传入三个参数:value
, row
和 column
。
:filters="tableFilter[item.prop]"
:filter-method="filterHandler"
tableFilter: {}, // 定义过滤的值
created() {
this.$nextTick(() => {
// 初始化时将table的所有数据赋值给tableFilter,即默认展示所有数据
this.handleFilter(this.tableData)
})
}
methods:{
// 过滤选中的值
filterHandler(value, row, column) {
const property = column['property']
// 过滤操作需要修改dom结构,因此需要用到 this.$nextTick
this.$nextTick(() => {
this.handleFilter(this.tableData, property) // 过滤完的列表数据,选中的属性
})
return row[property] === value // value是filters里绑定的数据里选中的项的value
},
// 过滤的方法
handleFilter(list, property) {
// 遍历展示列的每一列
this.finallyColumns.forEach(val => {
// 对每一列对应属性的值复制了一份且去重
let arr = new Set(
list.map(item => {
return item[val.prop]
})
)
// 将每一列的值格式化并放入到brr数组中
let brr = []
arr.forEach(item => {
brr.push({ value: item, text: item })
})
// 初始化时:没有选中的属性,将所有的值添加到过滤的数组中
if (property !== val.prop) {
/**
* this.$set( target, key, value)
* target:表示数据源,即是你要操作的数组或者对象
* key:要操作的的字段
* value:更改的数据
*/
this.$set(this.tableFilter, val.prop, brr)
}
})
},
}
3. 【配置列】
tocheckList: [], // 标志是否勾选
<el-table-column prop="tag" label="操作" width="200" show-overflow-tooltip>
<!--表头栏操作-->
<template slot="header">
操作
<!-- 筛选框 -->
<el-popover popper-class="popoverColumn" trigger="hover">
<el-checkbox-group v-model="tocheckList">
<el-checkbox
v-for="(item, index) in tableColums"
:key="item.id"
:label="item.label"
></el-checkbox>
</el-checkbox-group>
<span slot="reference">
<i class="el-icon-setting"></i>
</span>
</el-popover>
</template>
<el-button>删除</el-button>
</el-table-column>
created() {
// 将列表的label赋值给【el-checkbox-group】绑定的tocheckList,即默认默认展示所有列
this.tocheckList = this.tableColums.map(item => {
return item.label
})
},
methods: {
// 过滤【el-checkbox-group】绑定的tocheckList中未选中的列并赋值给finallyColumns
finallyColumns() {
let finallyArray = []
finallyArray = this.tableColums.filter(item =>
this.tocheckList.includes(item.label)
)
return finallyArray
}
}
4.【点击跳转】
<!-- 点击【姓名列】可以跳转 -->
<template slot-scope="{ row }">
<el-link
v-if="item.link"
:key="index"
:underline="false"
style="color: #409eff"
@click="handleClickRow(row, item)"
>{{ row[item.prop] }}
</el-link>
<span v-else>{{ row[item.prop] }}</span>
</template>
methods: {
// 点击链接可以实现跳转至详情页,这里简单化,只做了消息提示
handleClickRow(row, item) {
this.$message({
message: '欢迎' + row.name,
type: 'success'
})
}
}
下面附上完整代码:文章来源:https://uudwc.com/A/VNMvz
<template>
<div class="table">
<el-table :data="tableData" ref="table" :span-method="objectSpanMethod" border>
<el-table-column
v-for="(item, index) in finallyColumns"
sortable
align="center"
:key="item.id"
:prop="item.prop"
:label="item.label"
:filters="tableFilter[item.prop]"
:filter-method="filterHandler"
>
<!-- 点击【姓名列】可以跳转 -->
<template slot-scope="{ row }">
<el-link
v-if="item.link"
:key="index"
:underline="false"
style="color: #409eff"
@click="handleClickRow(row, item)"
>{{ row[item.prop] }}</el-link>
<span v-else>{{ row[item.prop] }}</span>
</template>
</el-table-column>
<el-table-column prop="tag" label="操作" width="200" show-overflow-tooltip>
<!--表头栏操作-->
<template slot="header">
操作
<!-- 筛选框 -->
<el-popover popper-class="popoverColumn" trigger="hover">
<el-checkbox-group v-model="tocheckList">
<el-checkbox
v-for="(item, index) in tableColums"
:key="item.id"
:label="item.label"
></el-checkbox>
</el-checkbox-group>
<span slot="reference">
<i class="el-icon-setting"></i>
</span>
</el-popover>
</template>
<el-button>删除</el-button>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: 'Form',
data() {
return {
// 表格数据
tableData: [
{
id: 1,
name: '张三',
date: '2022-11-6',
address: '上海市普陀区金沙江路 1516 弄上海市普陀区金沙江路',
phone: '22',
email: '11',
},
{
id: 2,
name: '李四',
date: '2022-11-16',
address: '上海市普陀区金沙江路 1516 弄上海市普陀区金沙江路',
phone: '33',
email: '11',
},
{
id: 3,
name: '张三',
date: '2022-11-2',
address: '上海市普陀区金沙江路 1516 弄上海市普陀区金沙江路',
phone: '444',
email: '11',
},
{
id: 4,
name: '张三',
date: '2022-11-6',
address: '上海市普陀区金沙江路 1516 弄上海市普陀区金沙江路',
phone: '55',
email: '11',
},
{
id: 5,
name: '张三',
date: '2022-11-8',
address: '上海市普陀区金沙江路 1516 弄上海市普陀区金沙江路',
phone: '66',
email: '111',
},
{
id: 6,
name: '张三',
date: '2022-11-7',
address: '上海市普陀区金沙江路 1516 弄上海市普陀区金沙江路',
phone: '77',
email: '112'
}
],
// 表头
tableColums: [
{
prop: 'name',
label: '姓名',
width: '180',
link: true
},
{
prop: 'date',
label: '日期',
width: '180'
},
{
prop: 'address',
label: '地址',
width: '180'
},
{
prop: 'phone',
label: '手机号码',
width: '180'
},
{
prop: 'email',
label: '邮箱',
width: '180'
}
],
tocheckList: [], // 标志是否勾选
tableFilter: {}, // 定义过滤的值
spanNumArr: [], // 合并行数
posNum: [], // 记录位置
}
},
created() {
this.$nextTick(() => {
// 初始化时将table的所有数据赋值给tableFilter,即默认展示所有数据
this.handleFilter(this.tableData)
})
// 将列表的label赋值给【el-checkbox-group】绑定的tocheckList,即默认默认展示所有列
this.tocheckList = this.tableColums.map(item => {
return item.label
})
// 获取合并行行数
this.getSpanNumArr(this.tableData)
},
computed: {
// 过滤【el-checkbox-group】绑定的tocheckList中未选中的列并赋值给finallyColumns
finallyColumns() {
let finallyArray = []
finallyArray = this.tableColums.filter(item =>
this.tocheckList.includes(item.label)
)
return finallyArray
}
},
methods: {
// 设置合并行
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
if (column.property == 'name') {
const _row = this.spanNumArr[rowIndex]
const _col = _row > 0 ? 1 : 0 // 0 值是为了去除错位
return {
rowspan: _row,
colspan: _col
}
}
},
// 获取合并行的行数
getSpanNumArr(data) {
this.spanNumArr = []
this.posNum = 0
for (var i = 0; i < data.length; i++) {
if (i === 0) {
this.spanNumArr.push(1)
this.posNum = 0
} else {
if (data[i].name === data[i - 1].name) {
this.spanNumArr[this.posNum] += 1
this.spanNumArr.push(0)
} else {
this.spanNumArr.push(1)
this.posNum = i
}
}
}
},
// 过滤选中的值
filterHandler(value, row, column) {
const property = column['property']
// 过滤操作需要修改dom结构,因此需要用到 this.$nextTick
this.$nextTick(() => {
this.handleFilter(this.tableData, property) // 过滤完的列表数据,选中的属性
})
return row[property] === value // value是filters里绑定的数据里选中的项的value
},
// 过滤的方法
handleFilter(list, property) {
// 遍历展示列的每一列
this.finallyColumns.forEach(val => {
// 对每一列对应属性的值复制了一份且去重
let arr = new Set(
list.map(item => {
return item[val.prop]
})
)
// 将每一列的值格式化并放入到brr数组中
let brr = []
arr.forEach(item => {
brr.push({ value: item, text: item })
})
// 初始化时:没有选中的属性,将所有的值添加到过滤的数组中
if (property !== val.prop) {
/**
* this.$set( target, key, value)
* target:表示数据源,即是你要操作的数组或者对象
* key:要操作的的字段
* value:更改的数据
*/
this.$set(this.tableFilter, val.prop, brr)
}
})
},
// 点击链接可以实现跳转至详情页,这里简单化,只做了消息提示
handleClickRow(row, item) {
this.$message({
message: '欢迎' + row.name,
type: 'success'
})
}
}
}
</script>
<style scoped>
h1 {
text-align: center;
}
.table {
width: 800px;
display: inline-block;
text-align: center;
margin-left: 50%;
transform: translate(-50%);
}
.el-checkbox-group {
display: flex;
flex-direction: column;
}
</style>
如有错误的地方,欢迎指正!文章来源地址https://uudwc.com/A/VNMvz