【vue】avue-crud中filter-change过滤事件问题

本文探讨了在使用avue-crud时,如何通过在column.vue中添加column-key属性,解决filter-change事件中判断列过滤条件的问题。作者提供了代码示例和配置tableOption的方法,以实现后台精确过滤功能。
摘要由CSDN通过智能技术生成

1.问题说明

1.准备在filter表头过滤时做后台查询过滤,但无法获取是哪一列
2.avue-crud的filter-change事件中未封装column信息,这样在filter-change方法回调的时候,参数里只有默认的column信息,如果过滤的表头过多,无法判断是哪个列的过滤改变
3.查看column.vue源码发现没有对el-table-colum加入column-key属性

2.代码示例

1.修改avue-crud源码中的column.vue,在el-table-column中加入属性:column-key=“column.columnKey”

<!--此为avue-crud中的源码,实际源码按官网为准,这里只做示范-->
<template>
  <div>
    <slot name="header"></slot>
    <!-- 动态列 -->
    <template v-for="(column,index) in list">
      <column-dynamic v-if="column.children && column.children.length"
                      :columnOption="column"
                      :key="column.label">
        <template v-for="item in crud.mainSlot"
                  slot-scope="scope"
                  :slot="item.prop">
          <slot v-bind="scope"
                :name="item.prop"></slot>
        </template>
        <template v-for="item in crud.headerSlot"
                  slot-scope="scope"
                  :slot="crud.getSlotName(item,'H')">
          <slot v-bind="scope"
                :name="crud.getSlotName(item,'H')"></slot>
        </template>
        <template v-for="item in crud.mainSlot"
                  slot-scope="scope"
                  :slot="crud.getSlotName(item,'F')">
          <slot v-bind="scope"
                :name="crud.getSlotName(item,'F')"></slot>
        </template>
      </column-dynamic>
      <template v-else-if="!['dynamic'].includes(column.type)">
        <el-table-column v-if="vaildColumn(column)"
                         :key="column.prop"
                         :prop="column.prop"
                         :label="column.label"
                         filter-placement="bottom-end"
                         :filters="handleFilters(column)"
                         :filter-method="column.filter? handleFiltersMethod : undefined"
                         :filter-multiple="vaildData(column.filterMultiple,true)"
                         :show-overflow-tooltip="column.overHidden"
                         :min-width="column.minWidth"
                         :sortable="column.sortable"
                         :render-header="column.renderHeader"
                         :align="column.align || tableOption.align"
                         :header-align="column.headerAlign || tableOption.headerAlign"
                         :column-key="column.columnKey"
                         :width="column.width"
                         :fixed="crud.isMobile?false:column.fixed">
          <template slot="header"
                    slot-scope="scope">
            <slot :name="crud.getSlotName(column,'H')"
                  v-if="crud.$scopedSlots[crud.getSlotName(column,'H')]"
                  v-bind="Object.assign(scope,{column})"></slot>
            <template v-else>{{column.label}}</template>
          </template>
          <template slot-scope="{row,$index}">
            <el-form-item :prop="crud.isTree?'':`list.${$index}.${column.prop}`"
                          :label="vaildLabel(column,row,' ')"
                          v-if="row.$cellEdit && column.cell"
                          :label-width="vaildLabel(column,row,'1px')"
                          :rules='column.rules'>
              <slot v-bind="{
                      row:row,
                      dic:crud.DIC[column.prop],
                      size:crud.isMediumSize,
                      index:$index,
                      disabled:crud.btnDisabledList[$index],
                      label:handleShowLabel(row,column,crud.DIC[column.prop]),
                      '$cell':row.$cellEdit
                    }"
                    :name="crud.getSlotName(column,'F')"
                    v-if="crud.$scopedSlots[crud.getSlotName(column,'F')]"></slot>
              <form-temp v-else
                         :column="column"
                         :size="crud.isMediumSize"
                         :dic="(crud.cascaderDIC[$index] || {})[column.prop] || crud.DIC[column.prop]"
                         :props="column.props || tableOption.props"
                         :readonly="column.readonly"
                         :disabled="crud.disabled || tableOption.disabled || column.disabled  || crud.btnDisabledList[$index]"
                         :clearable="vaildData(column.clearable,false)"
                         v-bind="$uploadFun(column,crud)"
                         v-model="row[column.prop]"
                         @change="columnChange(index,row,column)">
              </form-temp>
            </el-form-item>
            <slot :row="row"
                  :index="$index"
                  :dic="crud.DIC[column.prop]"
                  :size="crud.isMediumSize"
                  :label="handleShowLabel(row,column,crud.DIC[column.prop])"
                  :name="column.prop"
                  v-else-if="crud.$scopedSlots[column.prop]"></slot>
            <template v-else>
              <span v-if="['img','upload'].includes(column.type)">
                <div class="xiaoi-crud__img">
                  <img v-for="(item,index) in getImgList(row,column)"
                       :src="item"
                       :key="index"
                       @click="openImg(getImgList(row,column),index)" />
                </div>
              </span>
              <span v-else-if="['url'].includes(column.type)">
                <el-link v-for="(item,index) in corArray(row[column.prop],column.separator)"
                         type="primary"
                         :key="index"
                         :href="item"
                         :target="column.target || '_blank'">{{item}}</el-link>
              </span>
              <span v-else-if="['rate'].includes(column.type)">
                <xiaoi-rate disabled
                           v-model="row[column.prop]" />
              </span>
              <span v-else
                    v-html="handleDetail(row,column)"></span>
            </template>
          </template>
        </el-table-column>
      </template>
    </template>
    <slot name="footer"></slot>
  </div>

</template>

<script>

import create from "core/create";
import { detail } from "core/detail";
import { sendDic } from "core/dic";
import { DIC_PROPS, DIC_SPLIT } from 'global/variable'
import columnDynamic from "./column-dynamic";
import formTemp from '../../core/components/form/index'
export default create({
  name: "crud",
  data () {
    return {
      count: {}
    }
  },
  components: {
    formTemp,
    columnDynamic
  },
  inject: ["crud"],
  provide () {
    return {
      crud: this.crud,
      dynamic: this
    };
  },
  props: {
    tableOption: {
      type: Object,
      default: () => {
        return {};
      }
    },
    columnOption: {
      type: Array,
      default: () => {
        return [];
      }
    }
  },
  computed: {
    list () {
      let result = [...this.columnOption];
      return result;
    }
  },
  methods: {
    vaildLabel (column, row, val) {
      if (column.rules && row.$cellEdit) {
        return val
      }
    },
    vaildColumn (item) {
      return ((this.crud.$refs.dialogColumn || {}).columnIndex || []).includes(item.prop)
    },
    corArray (list, separator = DIC_SPLIT) {
      if (this.validatenull(list)) {
        return []
      } else if (!Array.isArray(list)) {
        return list.split(separator);
      }
      return list
    },
    getImgList (row, column) {
      let url = (column.propsHttp || {}).home || ''
      let value = (column.props || {}).value || DIC_PROPS.value;
      if (this.validatenull(row[column.prop])) return []
      if (column.listType == 'picture-img') return [url + row[column.prop]]
      let list = this.corArray(this.deepClone(row[column.prop]), column.separator);
      list.forEach((ele, index) => {
        if (typeof ele === 'object') {
          list[index] = url + ele[value];
        } else {
          list[index] = url + ele;
        }
      })
      return list;
    },
    handleDetail (row, column) {
      let result = row[column.prop];
      let DIC = column.parentProp ? (this.crud.cascaderDIC[row.$index] || {})[column.prop] : this.crud.DIC[column.prop]
      result = detail(row, column, this.tableOption, DIC);
      if (!this.validatenull(DIC)) {
        row["$" + column.prop] = result;
      }
      return result;
    },
    handleShowLabel (row, column, DIC) {
      let result = "";
      if (!this.validatenull(DIC)) {
        result = detail(row, column, this.tableOption, DIC);
        row["$" + column.prop] = result;
      }
      return result;
    },
    columnChange (index, row, column) {
      if (this.validatenull(this.count[column.prop])) this.count[column.prop] = 0
      this.count[column.prop] = this.count[column.prop] + 1;
      if (column.cascader) this.handleChange(index, row)
      if (this.count[column.prop] % 3 === 0 && typeof column.change === 'function' && column.cell === true) {
        column.change({ row, column, index: row.$index, value: row[column.prop] })
      }
    },
    handleChange (index, row) {
      this.$nextTick(() => {
        const columnOption = [...this.crud.propOption];
        //本节点;
        const column = columnOption[index];
        const list = column.cascader;
        const value = row[column.prop];
        const rowIndex = row.$index;
        // 下一个节点
        const columnNext = columnOption[index + 1];
        const columnNextProp = columnNext.prop;

        // 如果本节点没有字典则创建节点数组
        if (this.validatenull(this.crud.cascaderDIC[rowIndex])) {
          this.$set(this.crud.cascaderDIC, rowIndex, {});
        }
        if (this.crud.formIndexList.includes(rowIndex)) {
          //清空子类字典
          list.forEach(ele => {
            this.$set(this.crud.cascaderDIC[rowIndex], ele.prop, []);
            list.forEach(ele => (row[ele] = ""));
          });
        }
        //最后一级
        if (
          this.validatenull(list) ||
          this.validatenull(value) ||
          this.validatenull(columnNext)
        ) {
          return;
        }
        sendDic({
          column: columnNext,
          value: value,
          form: row
        }).then(
          res => {
            //首次加载的放入队列记录
            if (!this.crud.formIndexList.includes(rowIndex)) this.crud.formIndexList.push(rowIndex);
            const dic = Array.isArray(res) ? res : [];
            // 修改字典
            this.$set(this.crud.cascaderDIC[rowIndex], columnNextProp, dic);

            if (!this.validatenull(dic[columnNext.cascaderIndex]) && !this.validatenull(dic) && !this.validatenull(columnNext.cascaderIndex)) {
              row[columnNextProp] = dic[columnNext.cascaderIndex][(columnNext.props || {}).value || DIC_PROPS.value]
            }
          }
        );
      })

    },
    openImg (list, index) {
      list = list.map(ele => {
        return { thumbUrl: ele, url: ele }
      })
      this.$ImagePreview(list, index);
    },
    //表格筛选逻辑
    handleFiltersMethod (value, row, column) {
      const columnNew = this.columnOption.filter(
        ele => ele.prop === column.property
      )[0];
      if (typeof columnNew.filtersMethod === "function") {
        return columnNew.filtersMethod(value, row, columnNew);
      } else {
        return row[columnNew.prop] === value;
      }
    },
    //表格筛选字典
    handleFilters (column) {
      if (column.filter !== true) return undefined;
      if (this.validatenull(column.dicFilters)) {
        let list = [];
        (this.crud.DIC[column.prop] || []).forEach(ele => {
          const props = column.props || this.tableOption.props || {};
          list.push({
            text: ele[props.label || DIC_PROPS.label],
            value: ele[props.value || DIC_PROPS.value]
          });
        });
        return list;
      }
      return column.dicFilters;
    }
  }
});
</script>

2.tableOption中的配置,添加配置columnKey: ‘status’

export const tableOption = {
  menu: true,
  index: false,
  indexLabel: '序号',
  stripe: true,
  menuWidth: '100px',
  menuAlign: 'center',
  align: 'center',
  editBtn: false,
  delBtn: true,
  delBtnDisabled: false,
  addBtn: false,
  dic: [],
  searchMenuShow: false,
  selection: true,
  emptyText: '暂无数据',
  dialogType: 'drawer',
  labelPosition: 'top',
  column: [
    {
      label: '状态',
      prop: 'status',
      width: 110,
      slot: true,
      filter: true,
      filterMultiple: false,
      columnKey: 'status',
      dicData: [{ label: '待训练', value: 20 }, { label: '已生效', value: 15 }, { label: '已禁用', value: 1 }, { label: '同步失败', value: 10 }, { label: '同步中', value: 5 }],
      filterMethod: function(value, row) {
        return row.status === value
      }
    }
  ]
}

3.avue-curd代码中,添加filter-change事件

<avue-crud
      ref="crud"
      :option="tableOption"
      :page.sync="page"
      :data="tableData"
      :table-loading="tableLoading"
      @on-load="getList"
      @filter-change="filterChange"
    >
 </avue-crud>

4.filterChange方法代码

methods: {
    filterChange(filters){
    //如果不配置columnKey,filters的key默认为column数字,无法判断是哪一列,配置了columnKey便能判断是哪一列的过滤条件,根据这个过滤条件便可以进行后端过滤操作
      if(filters && filters.status != undefined) {
        var array = filters.status;
        var status = '';

        array.forEach(element => {
          status += element + ','
        });
        if(status.indexOf(",")){
          status = status.substring(0,status.length-1)
        }
        this.searchForm.searchStatus = status;
        this.getList(this.page)
      }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王佑辉

老板,赏点吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值