el-table 列表表头过滤功能单独开发

<CommonFilter v-if="item.type === 'filter'" :column="scope.column" :field-name="item.prop" filter-type="checkbox" :custom-arr-list="item.filterList" @tableFilter="tableFilter" @resetFilter="tableFilterReset" />

<template>
  <div style="display: inline-block" @click.stop>
    <el-popover ref="popover" placement="bottom" title="查询条件" width="240" trigger="click">
      <!-- 单个文本框 -->
      <div v-if="filterType == 'text'">
        <el-input v-model.trim="conditions.text" size="mini" clearable placeholder="请输入查询内容" @keyup.native.enter="confirm()" />
      </div>
      <!-- 数值范围 -->
      <div v-else-if="filterType == 'number'">
        <el-input v-model.trim="conditions.number1" size="mini" clearable type="number" step="0.01" placeholder="请输入开始数值" />
        <el-input v-model.trim="conditions.number2" size="mini" clearable step="0.01" style="margin-top: 10px" placeholder="请输入结束数值" />
      </div>
      <!-- 日期-->
      <div v-else-if="filterType == 'date'">
        <el-date-picker v-model="conditions.date1" type="date" clearable size="mini" placeholder="开始时间" value-format="yyyy-MM-dd" />
        <el-date-picker v-model="conditions.date2" style="margin-top: 10px" type="date" size="mini" clearable placeholder="结束时间" value-format="yyyy-MM-dd" />
      </div>
      <!-- 下拉框-->
      <div v-else-if="filterType == 'select'">
        <el-select v-model="conditions.select" placeholder="请选择" size="mini" clearable>
          <el-option v-for="(item, index) in customArrListCur" :key="index" :label="item.label" :value="item.value" />
        </el-select>
      </div>
      <!-- 复选框-->
      <div v-else-if="filterType == 'checkbox'">
        <el-input v-model="searchValue" placeholder="输入关键词" @input="searchChange"><svg-icon slot="prefix" icon-class="searchn" style="margin: 0 0 0 3px;" /></el-input>
        <div class="check-wrap">
          <div class="check-btn">
            <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全部 ({{99}}/{{99}})</el-checkbox>
            <div @click="handleCheckReverseChange">反选</div>
          </div>
          <el-checkbox-group v-model="conditions.checkbox" @change="handleCheckedCitiesChange">
            <el-checkbox v-for="(item, index) in customArrListCur" :key="index" :label="item.value">{{ item.label }} ({{99}})</el-checkbox>
          </el-checkbox-group>
        </div>
      </div>
      <!--单选按钮-->
      <div v-else-if="filterType == 'radio'">
        <el-radio-group v-model="conditions.radio">
          <el-radio v-for="(item, index) in customArrListCur" :key="index" border :label="item.value" size="mini">{{ item.label }}</el-radio>
        </el-radio-group>
      </div>
      <!-- confirm 确定框-->
      <div class="text-right mgt10">
        <el-button type="text" size="mini" @click="reset" icon="el-icon-refresh-right">重置</el-button>
        <el-button type="" size="mini" @click="cancel">取消</el-button>
        <el-button type="primary" size="mini" @click="confirm">确定</el-button>
      </div>
      <!-- 标题-->
      <span slot="reference" onselectstart="return false" oncontextmenu="return false" :class="labelColor">
        <svg-icon :icon-class="'guolv'" style="width: 14px; height: 14px; margin: -2px 0 0 5px;cursor: pointer;" />
      </span>
    </el-popover>
  </div>
</template>
<script>
export default {
  name: 'FilterHeader',
  props: {
    column: {
      type: Object,
      defalut: null
    },
    fieldName: {
      type: String,
      defalut: ''
    },
    filterType: {
      type: String,
      defalut: 'txt'
    },
    customArrList: {
      type: Array,
      defalut: []
    }
  },
  data() {
    return {
      searchValue: '',
      checkAll: false,
      isIndeterminate: false,
      conditions: {
        text: '',
        number1: '',
        number2: '',
        date1: '',
        date2: '',
        select: '',
        checkbox: [],
        radio: '',
      },
      customArrListCur: []
    }
  },
  computed: {
    // 有条件的话高亮显示标题
    labelColor() {
      switch (this.filterType) {
        case 'text':
          if (this.conditions.text) { return 'heighLight' }
          return ''
        case 'number':
          if (this.conditions.number1 || this.conditions.number2) { return 'heighLight' }
          return ''
        case 'date':
          if (this.conditions.date1 || this.conditions.date2) { return 'heighLight' }
          return ''
        case 'select':
          if (this.conditions.select) { return 'heighLight' }
          return ''
        case 'checkbox':
          if (this.conditions.checkbox.length > 0) { return 'heighLight' }
          return ''
        case 'radio':
          if (this.conditions.radio !== '') { return 'heighLight' }
          return ''
      }
      return ''
    },
  },
  watch: {
    customArrList: {
      handler(val) {
        this.customArrListCur = JSON.parse(JSON.stringify(val));
      },
      deep: true,
      immediate: true
    },
  },
  methods: {
    searchChange(val) {
      this.customArrListCur = this.customArrList.filter(item => {
        return item.value.indexOf(val) != -1;
      })
    },
    handleCheckReverseChange() {
      if (this.conditions.checkbox.length === 0) {
        this.conditions.checkbox = this.customArrListCur.map(item => item.value);
        this.checkAll = true;
      } else if (this.conditions.checkbox.length === this.customArrListCur.length) {
        this.conditions.checkbox = [];
        this.checkAll = false;
      } else {
        let list = this.customArrListCur.filter((v, i) => {
          return this.conditions.checkbox.indexOf(v.value) === -1;
        });
        this.conditions.checkbox = list.map(item => item.value);
      }
    },
    handleCheckAllChange(val) {
      this.conditions.checkbox = val ? this.customArrListCur.map(item => item.value) : [];
      this.isIndeterminate = false;
    },
    handleCheckedCitiesChange(value) {
      let checkedCount = value.length;
      this.checkAll = checkedCount === this.customArrListCur.length;
      this.isIndeterminate = checkedCount > 0 && checkedCount < this.customArrListCur.length;
    },
    confirm() {
      this.$refs.popover.doClose()
      this.$emit('tableFilter', {
        filterType: this.filterType,
        fieldName: this.fieldName,
        conditions: this.conditions
      })
    },
    cancel() {
      this.$refs.popover.doClose();
    },
    reset() {
      this.isIndeterminate = false;
      this.checkAll = false;
      switch (this.filterType) {
        case 'text':
          this.conditions.text = ''
          break
        case 'number':
          this.conditions.number1 = ''
          this.conditions.number2 = ''
          break
        case 'date':
          this.conditions.date1 = ''
          this.conditions.date2 = ''
          break
        case 'select':
          this.conditions.select = ''
          break
        case 'checkbox':
          this.conditions.checkbox = []
          break
        case 'radio':
          this.conditions.radio = ''
          break
      }
      // this.$refs.popover.doClose()
      this.$emit('resetFilter', {
        filterType: this.filterType,
        fieldName: this.fieldName,
        conditions: this.conditions
      })
    }
  }
}
</script>
<style scoped lang="scss">
.label {
  user-select: none;
}
.heighLight {
  color: #409eff;
}
.filter-radio {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  .el-radio {
    width: 45%;
    margin-right: 0;
  }
}
.check-wrap ::v-deep {
  border: 1px solid #dcdfe6;
  padding: 5px 10px;
  margin: 10px 0;
  .check-btn {
    display: flex;
    align-items: center;
    justify-content: space-between;
    border-bottom: 1px solid #dcdfe6;
    padding: 0 0 4px 0;
    div {
      cursor: pointer;
    }
  }
  .el-checkbox-group {
    height: 150px;
    overflow: auto;
    .el-checkbox {
      display: block;
      margin: 5px 0;
    }
  }
}
.text-right {
  display: flex;
  justify-content: right;
  gap: 0 10px;
}
.el-button {
  padding: 0 !important;
  border-radius: 2px;
  width: 54px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值