Vue2 & Vue3 二次封装element-ui table-Filter组件,分离过滤条件和表

  • Post author:
  • Post category:vue




前言

起因是要做一个这样的功能:

在这里插入图片描述

点击过滤按钮之后展开这些选项,然后点击搜索,为下面表格执行筛选数据的逻辑

element-ui自带的表格过滤功能虽然强大,传递指定参数后就可以在表头出现一个下拉框然后过滤数据,但是我要做的不是这个效果啊qwq(鼠鼠调了两天ele最后才发现过滤只能出现在表头,怨念极重,我说怎么传这点就可以实现过滤了)

然后这个过滤功能咋实现呢?目前还不知道,现在的思路是把这些收集好的过滤项,做成表单发请求传出去。

组件就接收一个msg,是整个表给我的一个id,然后我通过这个id,可以查到整个表的内容,再从tabledata中得到filterdata(筛选条件)

filterdata一般来说就是表的每一列,在这里以对象数组的形式去处理它,每个对象有name(属性名),val(值),这样就可以做除了时间条的条件渲染了。val为空字符串就说明是input,给了东西就加到select里,但是如果要加入时间条,这里就得多一个type(类型,是input还是select、time)来判断要生成什么样的表单元素。



代码



version1:实现基础功能

实现了一个计算属性筛表格的逻辑,也做了表单提交数据的行为

数据都是直接用的假数据,但是也实现了根据数据动态生成元素

还要解决的问题:

  1. 怎么写css,给不确定的元素个数弄上兼容的统一样式(目前的思路是ele的栅格布局)
  2. 过滤逻辑怎么写,前端用js能不能封装出一个“搜索”功能,提交对应内容去表单里筛东西,这里就直接调这个函数就可以了
  3. 暂时还是用的vue2+js的配置,还需要重构一下转成Vue3+ts(要是接受数据的话得写interface和类型守卫,ts是必须要用的
<template>
  <el-button @click="IsshowFilter = !IsshowFilter">过滤</el-button>

  <div class="filter-bar" v-show="IsshowFilter">
    <div class="filter-left">
      <el-form inline="true" label-position="right">
        <form-item
          v-for="(item, index) in info.itemArr"
          :key="index"
          class="filter-items"
        >
          <el-form-item
            :label="item.name"
            v-show="typeof item.val === 'string'"
          >
            <el-input placeholder="" v-model="form.itemArr[index].val" />
          </el-form-item>

          <el-form-item
            :label="item.name"
            v-show="typeof item.val === 'object'"
          >
            <el-select
              placeholder="请选择..."
              v-model="form.itemArr[index].val"
              clearable
            >
              <el-option
                v-for="context in item.val"
                :label="context"
                :value="context"
                :key="context"
              />
            </el-select>
          </el-form-item>
        </form-item>
      </el-form>
    </div>
    <div class="filter-right">
      <el-button @click="resetFilter">重置</el-button>
      <el-button type="primary" @click="submitFilter">搜索</el-button>
    </div>
  </div>
  <!-- table数据模拟 -->
  <el-table :data="filteredTableData">
    <el-table-column prop="zuzhi" label="组织" width="180" />
    <el-table-column prop="xinming" label="姓名" width="180" />
    <el-table-column prop="zhengjianhao" label="证件号" />
  </el-table>
</template>

<script>
export default {
  name:"Filter",
  data() {
    return {
      IsshowFilter: false,
      tableData: [
        { zuzhi: "成都分公司", xinming: "sayori", zhengjianhao: 123 },
        { zuzhi: "蓝海", xinming: "sayoriqwq", zhengjianhao: 12 },
        { zuzhi: "成都蓝海", xinming: "saqwq", zhengjianhao: 12344 },
      ],

      info: {
        itemArr: [
          {
            name: "组织",
            val: ["成都分公司", "蓝海"],
          },
          {
            name: "姓名",
            val: "",
          },
          {
            name: "证件号码",
            val: "",
          },
        ],
      },

      form: {
        itemArr: [
          {
            name: "组织",
            val: "",
          },
          {
            name: "姓名",
            val: "",
          },
          {
            name: "证件号码",
            val: "",
          },
        ],
      },
    };
  },
  mounted() {
    sessionStorage.setItem("formData", JSON.stringify(this.form));
  },
  computed: {
    filteredTableData() {
      return this.tableData.filter((item) => {
        const Match1 = item.xinming.includes(this.form.itemArr[1].val);
        const Match2 = item.zuzhi.includes(this.form.itemArr[0].val);
        const Match3 = item.zhengjianhao
          .toString()
          .includes(this.form.itemArr[2].val);

        return Match1 && Match2 && Match3;
      });
    },
  },
  methods: {
    async submitFilter() {
      console.log("带着筛选过的内容发请求", this.form);
    },
    resetFilter() {
      this.form = JSON.parse(sessionStorage.getItem("formData"));
    },
  },
};
</script>

<style scoped>
.filter-bar {
  display: flex;
}
</style>



待续



版权声明:本文为qq_64036795原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。