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