el-table一键开启表格筛选
el-table 一键开启表格筛选。
- el-table提供了表格筛选api,但是需要自行对每列设置,而且筛选数据需要自己填充。
<el-table-column
prop="date"
label="日期"
sortable
width="180"
column-key="date"
:filters="[{text: '2016-05-01', value: '2016-05-01'}, {text: '2016-05-02', value: '2016-05-02'}, {text: '2016-05-03', value: '2016-05-03'}, {text: '2016-05-04', value: '2016-05-04'}]"
:filter-method="filterHandler"
>
- 对于老项目进行增加表格筛选功能时改动量会非常大,为了解决这个问题,灵机一动,想到使用指令来批量处理,代码如下:
/**
* 表格开启筛选
*
* @example v-el-table-filter
* @example v-el-table-filter="filterProps"
*/
const install = (Vue) => {
Vue.directive('el-table-filter', {
bind(el, binding, node) {
doWork(el, binding, node)
}
})
}
const doWork = (el, binding, node) => {
const {service, format, except, filterMethod} = binding.value || {}
node.componentInstance.$watch('data', (newValue) => {
if (!newValue || !newValue.length) {
return
}
node.componentInstance.store.states.columns.forEach(column => {
const property = column.property
// 排除字段
if (except && except.includes(property)) {
return
}
const filterSet = new Set(newValue
.map(item => item[property])
.filter(value => value !== undefined)
.filter(v => (typeof v === 'string' || v instanceof String) ? !!v.trim() : true)
)
if (!filterSet.size) {
return
}
let filterList = Array.from(filterSet)
// 调用格式化
if (format && format[property]) {
const func = format[property]
filterList = filterList.map(value => {
const formatValue = func(value)
const filterValue = {
text: null,
value: value
}
// 异步方法
if (formatValue instanceof Promise) {
formatValue.then(v => filterValue.text = v)
} else {
filterValue.text = formatValue
}
return filterValue
})
} else {
filterList = filterList.map(value => {
return {
text: value,
value: value
}
})
}
// 开启筛选
column.filterable = true
column.filters = filterList
if (service) {
return
}
// 筛选方法
if (binding.value && filterMethod && filterMethod[property]) {
column.filterMethod = filterMethod[property]
} else {
column.filterMethod = function (value, row, column) {
const property = column.property
return row[property] === value
}
}
})
})
}
export default install
- 食用方法:
main.js
import Vue from 'vue'
import elTableFilter from "@/directive/el-table-filter/el-table-filter"
Vue.use(elTableFilter)
demo
<el-table
ref="table"
border
:data="dataList"
row-key="id"
v-el-table-filter="filterProps"
@filter-change="onFilterChange"
v-el-table-sortable
>
</el-table>
- 参数说明:
filterProps: {
// 开启服务端筛选,前端不做筛选方法调用,正常回调筛选事件
service: false,
// 筛选数据显示格式化,定义时使用箭头函数,可异步方法
format: {
value1: (value) => {
// 调用外部方法使用call绑定this
return this.$func.call(this, value)
},
value2: (value) => {
return this.func()
}
},
// 自定义筛选方法,默认判定值相等
filterMethod: {
state: (value, row, column) => {
return row[column.property] === value
}
},
// 排除筛选列
except: ['prop1', 'prop2']
}
- 一键开启排序一并奉上
const install = (Vue) => {
Vue.directive('el-table-sortable', {
bind(el, binding, node) {
doWork(el, binding, node)
}
})
}
const doWork = (el, binding, node) => {
const {except} = binding.value || {}
node.componentInstance.$watch('data', (newValue) => {
if (node.componentInstance.sortable) {
return
}
node.componentInstance.store.states.columns.forEach(column => {
const property = column.property
// 排除字段
if (except && except.includes(property)) {
return
}
// 开启筛选
column.sortable = true
})
node.componentInstance.sortable = true
})
}
export default install