element表格筛选:联动接口查询
element表格组件并不支持后端筛选, 并且官方文档对筛选功能描述十分模糊,
本篇文章是基于element-ui组件, 通过事件监听器、公共样式修改、局部更新表格组件、深拷贝数组实现如下功能:
- 筛选联动接口查询
- 多选条件筛选
- 排他性筛选(只允许一个筛选条件)
- 下三角样式重写为漏斗样式
- 选中时漏斗高亮
- 筛选列表失焦时,漏斗取消高亮
- 筛选按钮样式重写(文字改按钮,按钮靠左,按钮禁用淡蓝样式,筛选->确定,重置->清空,两按钮交换位置)
1. 筛选联动接口查询
只需配置如下element属性即可实现:
@filter-change="filterHandler" // 筛选改变事件
:filters="filterParams[item.key]" // 筛选列表
:filtered-value="filterValue[item.key]" // 已筛选的值
:column-key="item.key" // 筛选字段key(用于筛选事件的响应参数)
<!-- filter-change 为确定筛选方法 -->
<el-table
:data="tableData.body"
row-key="id"
@filter-change="filterHandler"
>
<!--
filters:筛选选项数组
filtered-value:筛选值
column-key:筛选字段的key -->
<el-table-column
v-for="item in tableData.head"
:key="item.key"
:label="item.name"
:prop="item.key"
:filters="filterParams[item.key]"
:filtered-value="filterValue[item.key]"
:column-key="item.key"
>
</el-table-column>
</el-table>
<script>
export default {
data() {
return {
filterValue: {} // 筛选值
},
computed: {
/*
筛选列表:包含所有可筛选的字段
模板:
filterParams: {
connectionStatus: [
{ text: '在线', value: '在线' },
{ text: '离线', value: '离线' }
]
}
*/
filterParams() {
const resObj = { alarmSeverityId: [] }
;['', '正常', '警告', '次要', '主要', '严重'].forEach((item, index) => {
if (index !== 0) {
resObj.alarmSeverityId.push({ text: item, value: index })
}
})
return resObj
},
methods: {
// 联动后端筛选方法
filterHandler(obj) {
const key = Object.keys(obj)[0] // 筛选项的key
this.filterValue = {}
if (obj[key].length !== 0) {
this.filterValue[key] = obj[key] // 同步筛选list
}
this.getTableData()
},
// 获取列表数据
getTableData() {
const params = {
pageNum: this.pageNum,
pageSize: this.pageSize,
obj: { ...this.searchForm , ...this.filterValue } // 将筛选值传入请求参数中
}
getNetworkElementList(params) // 发起请求
}
}
}
</script>
所有代码实现如下
<!-- :key="Math.random()" 在筛选值变化时刷新漏斗样式 -->
<!-- filter-change 为确定筛选方法 -->
<el-table
:key="Math.random()"
:data="tableData.body"
row-key="id"
@filter-change="filterHandler"
>
<!--
filters:筛选选项数组
filtered-value:筛选值
column-key:筛选字段的key -->
<el-table-column
v-for="item in tableData.head"
:key="item.key"
:label="item.name"
:prop="item.key"
:filters="filterParams[item.key]"
:filtered-value="filterValue[item.key]"
:column-key="item.key"
>
<template slot-scope="scope">
<template v-if="item.key === 'name'">
<span class="param-link" @click="openParamTab(scope.row)">
{{ scope.row.name }}
</span>
</template>
<template v-else>{{ scope.row[item.key] }}</template>
</template>
</el-table-column>
</el-table>
<script>
export default {
data() {
return {
filterValue: {} // 筛选值
},
computed: {
/*
筛选列表:包含所有可筛选的字段
模板:
filterParams: {
connectionStatus: [
{ text: '在线', value: '在线' },
{ text: '离线', value: '离线' }
]
}
*/
filterParams() {
const resObj = { alarmSeverityId: [] }
;['', '正常', '警告', '次要', '主要', '严重'].forEach((item, index) => {
if (index !== 0) {
resObj.alarmSeverityId.push({ text: item, value: index })
}
})
return resObj
},
mounted() {
this.getTableData()
document.addEventListener('click', this.clickOutsideHandler) // 点击外部的事件监听器
},
beforeDestroy() {
document.removeEventListener('click', this.clickOutsideHandler) // 注销事件监听器
},
methods: {
// 点击外部时,刷新筛选值
clickOutsideHandler() {
const cloneFilterValue = JSON.parse(JSON.stringify(this.filterValue))
Object.keys(this.filterValue).forEach(key => {
this.filterValue[key] = []
})
this.$nextTick(() => {
// 重置为此前确定的筛选值
this.filterValue = cloneFilterValue
})
},
// 联动后端筛选方法
filterHandler(obj) {
const key = Object.keys(obj)[0] // 筛选项的key
this.filterValue = {}
if (obj[key].length !== 0) {
this.filterValue[key] = obj[key] // 同步筛选list
}
this.getTableData()
},
// 获取列表数据
getTableData() {
const params = {
pageNum: this.pageNum,
pageSize: this.pageSize,
obj: { ...this.searchForm , ...this.filterValue } // 将筛选值传入请求参数中
}
getNetworkElementList(params) // 发起请求
}
}
}
</script>
/*全局公共样式*/
<style>
// 筛选框内部样式(文字改按钮,按钮靠左,按钮禁用淡蓝样式,筛选->确定,重置->清空,两按钮交换位置)
.el-table-filter__wrap.el-scrollbar__wrap {
margin-bottom: 0px !important;
}
.el-table-filter__bottom {
height: 45px;
button:after {
position: absolute;
background-color: #fff;
padding: 2px 5px;
border-radius: 3px;
}
button:nth-child(1):after {
left: 55px;
content: '确定';
background-color: $themeColor;
border: $themeColor 1px solid;
}
.is-disabled:nth-child(1):after {
border: #a8c7fb 1px solid !important;
background-color: #a8c7fb;
}
button:nth-child(2):after {
left: 6px;
content: '清除';
color: #6b6b6b !important;
border: #989898 1px solid;
}
button:nth-child(2):hover:after {
color: $themeColor !important;
border: $themeColor 1px solid;
}
button {
color: #fff !important;
}
}
// 筛选图标样式(使用伪类, 画倒三角和长方形组合为漏斗)
.el-table__column-filter-trigger {
.el-icon-arrow-down {
transform: translateY(25%);
box-sizing: border-box;
margin-left: 5px;
}
.el-icon-arrow-down:before {
content: '';
display: inline-block;
width: 15px;
height: 15px;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-top: 7px solid #767575;
}
.el-icon-arrow-down:after {
position: absolute;
content: '';
display: inline-block;
left: 5px;
height: 13px;
background-color: #767575;
width: 4px;
}
}
// 高亮时添加highlight类, 使用主题色
.cell.highlight {
color: $tableHeaderColor !important;
}
.cell.highlight .el-table__column-filter-trigger .el-icon-arrow-down:before {
border-top: 7px solid #508ff6;
}
.cell.highlight .el-table__column-filter-trigger .el-icon-arrow-down:after {
background-color: #508ff6;
}
</style>