先看效果图

一、前言

甲方放着好好的导出,好好的excel的高级筛选不用,非要在网页中实现一个。。。。

最开始尝试使用的element官方的筛选,给甲方看后 说和excel的筛选相差很大。。好在官方有提供自定义表头,那自己手动实现一个了。最后有完整代码

其实此功能挺简单的,只不过麻烦一点。我把筛选分为了四个类型

  1. txt 文本型  (就是input输入框)
  2. scope 范围型 (查询金额区间)
  3. date 时间型 (查询日期)
  4. select 下拉框 (就是下拉框呗)

整体逻辑就是:子组件把筛选好的数据,给父组件,父组件进行筛选过滤,再给table展示

二、父组件

分为两个部分

1.tag部分,显示所用到的筛选条件

2.table部分

html

   <!-- 条件tag --><div style="margin-bottom: 10px" v-if="conditionList.length != 0"><span>条件:</span><el-tag@close="conditionClose(index)"style="margin-left: 10px"v-for="(tag, index) in conditionList":key="index"closable:type="tag.prop">{{ tag.label }} :<span style="color: red">{{ tag.value.value1 }}</span><span v-if="tag.value.value2" style="color: red">- {{ tag.value.value2 }}</span></el-tag></div><!-- 表格 --><el-table :data="tableData" style="width: 100%" border stripe><template v-for="(item, index) in tableConfig"><el-table-columnsortable:key="index":label="item.label"align="center":prop="item.prop":width="item.width":filters="[]"><template slot="header" slot-scope="scope"><custom-headerv-if="customFlag":column="scope.column":item="item":customParams="customParams":labelColorList="labelColorList"@tableUpdate="tableUpdate"></custom-header></template></el-table-column></template></el-table>

custom-header 为子组件,里面写着四个类型的代码

父data里的数据

  data() {return {customFlag: false, // 自定义筛选是否显示customParams: {}, //自定义筛选参数conditionList: [], //自定义筛选条件labelColorList: [], //已经在使用的筛选条件,染色用// table数据tableData: [],// table数据 拷贝,我们不操作原数据tableDataCopy: [],// table配置tableConfig: [{label: "姓名",prop: "name",width: "150px",conditionType: "txt", // 条件类型},{label: "身价",prop: "amount",width: "150px",conditionType: "scope", // 条件类型},{label: "生日",prop: "date",width: "150px",conditionType: "date", // 条件类型},{label: "所在城市",prop: "city",conditionType: "select", // 条件类型conditionListName: "cityList", //条件类型下拉框数据fuzzyQuery: false, //是否模糊查询},{label: "所在城市(模糊查询)",prop: "city2",conditionType: "select", // 条件类型conditionListName: "cityList", //条件类型下拉框数据fuzzyQuery: true, //是否模糊查询},],};},

tableConfig里的数据会被el-table遍历

其中:

        conditionType : 条件的类型,前言已经说了就是那四个类型(txt,scope,date,select)

        conditionListName:  如果是select类型的话,肯定有下拉框数据对吧,这个就是下拉框数据的List名,只是名字不是数据哦(不明白的话看到子组件那里就懂了)

        fuzzyQuery:是否模糊查询

父methods几个关键方法

  methods: {// 请求下拉框数据getCustomData() {},//给使用筛选条件的标题加颜色setlabelColor() {},//自定义检索发射出来的事件tableUpdate() {},//筛选数据customSearch() {},}

getCustomData():汇总下拉框的数据

customSearch():筛选逻辑处理,后面想改筛选的逻辑就来这。后面贴出的完整代码里写的也很清楚,不明白可以问我

三、子组件

接收的props

column:当前列数据,用于显示表头

tableConfig :处理类型判断

customParams :select下拉框数据

labelColorList :正在使用的筛选条件,染色用

computed

  computed: {selectList() {return function (data) {return this.customParams[data.conditionListName];};},},

根据下拉框名称,找到对应的下拉框List数据

其他没什么说的,子组件比较简单,看完整代码一眼就明白了

四、完整代码

父组件

<template><div class="app"><!-- 条件tag --><div style="margin-bottom: 10px" v-if="conditionList.length != 0"><span>条件:</span><el-tag@close="conditionClose(index)"style="margin-left: 10px"v-for="(tag, index) in conditionList":key="index"closable:type="tag.prop">{{ tag.label }} :<span style="color: red">{{ tag.value.value1 }}</span><span v-if="tag.value.value2" style="color: red">- {{ tag.value.value2 }}</span></el-tag></div><!-- 表格 --><el-table :data="tableData" style="width: 100%" border stripe><template v-for="(item, index) in tableConfig"><el-table-columnsortable:key="index":label="item.label"align="center":prop="item.prop":width="item.width":filters="[]"><template slot="header" slot-scope="scope"><custom-headerv-if="customFlag":column="scope.column":item="item":customParams="customParams":labelColorList="labelColorList"@tableUpdate="tableUpdate"></custom-header></template></el-table-column></template></el-table></div>
</template>
<script>
import customHeader from "./components/customHeader.vue";
export default {name: "app",data() {return {customFlag: false, // 自定义筛选是否显示customParams: {}, //自定义筛选参数conditionList: [], //自定义筛选条件labelColorList: [], //已经在使用的筛选条件,染色用// table数据tableData: [],// table数据 拷贝,我们不操作原数据tableDataCopy: [],// table配置tableConfig: [{label: "姓名",prop: "name",width: "150px",conditionType: "txt", // 条件类型},{label: "身价",prop: "amount",width: "150px",conditionType: "scope", // 条件类型},{label: "生日",prop: "date",width: "150px",conditionType: "date", // 条件类型},{label: "所在城市",prop: "city",conditionType: "select", // 条件类型conditionListName: "cityList", //条件类型下拉框数据fuzzyQuery: false, //是否模糊查询},{label: "所在城市(模糊查询)",prop: "city2",conditionType: "select", // 条件类型conditionListName: "cityList", //条件类型下拉框数据fuzzyQuery: true, //是否模糊查询},],};},methods: {getCustomData() {/*这里的数据有必要注意下:1.数据格式这里处理好 全部保持一致,这样customHeader就不用再处理了3.因为我们后面筛选的时候查找的是文字,所以这里的value始终和列表展示的值保持一致,也是文字。3.可以写个Promise.All,把下拉框所需要的数据都请求到 然后再打开customFlag*/this.customParams = {//城市列表cityList: [{ value: "北京市" },{ value: "南京市" },{ value: "上海市" },{ value: "广州市" },{ value: "深圳市" },{ value: "杭州市" },{ value: "成都市" },],// ...};this.customFlag = true;},// 给使用筛选条件的标题加颜色setlabelColor() {this.labelColorList = [];this.conditionList.forEach((_item) => {this.labelColorList.push(_item.prop);});},// 自定义检索发射出来的事件tableUpdate(data) {console.log(data, "condition");let flag = true;// 筛选条件如果已经存在,就更新this.conditionList.forEach((item, index) => {if (item.prop == data.prop) {item.value = data.value;flag = false;}});// 如果没有就添加if (flag) {this.conditionList.push(data);}this.customSearch(); //筛选数据},// 筛选数据customSearch() {/*这里可以说是筛选的核心部分吧,自定义的筛选规则都在这。以后想改什么筛选规则就来这找*/console.log(this.conditionList, "this.conditionList");this.setlabelColor(); //设置使用自定义检索的表头颜色// 如果自定义检索 为空了,就重新调用查询if (this.conditionList.length == 0) {this.search();return false;}const result = [];// 遍历列表数据for (let i = 0; i < this.tableDataCopy.length; i++) {const dataItem = this.tableDataCopy[i];// 遍历自定义筛选条件,符合规则就push出来let flag = true;for (let l = 0; l < this.conditionList.length; l++) {const item = this.conditionList[l];// 属性名 属性值 类型 是否模糊查询const { prop, value, conditionType, fuzzyQuery } = item;// txt类型if (conditionType == "txt") {if (dataItem[prop].indexOf(value.value1) != -1) {flag = true;} else {flag = false;}//范围类型} else if (conditionType == "scope") {if (dataItem[prop] >= value.value1 &&dataItem[prop] <= value.value2) {flag = true;} else {flag = false;}// 时间类型} else if (conditionType == "date") {// 转换为时间戳然后判断let current = new Date(dataItem[prop]).getTime();let value1 = new Date(value.value1).getTime();let value2 = new Date(value.value2).getTime();if (current >= value1 && current <= value2) {flag = true;} else {flag = false;}}// 下拉框类型else if (conditionType == "select") {// fuzzyQuery 为true代表模糊查询,否则为精确查询if (fuzzyQuery) {if (dataItem[prop].indexOf(value.value1) != -1) {flag = true;} else {flag = false;}} else {if (dataItem[prop] == value.value1) {flag = true;} else {flag = false;}}}if (flag === false) break;}if (flag) result.push(dataItem);}console.log(result, "result");this.tableData = result;// this.totalSize = result.length;},search() {this.tableData = [{name: "王小虎",amount: 100,date: "2018-05-02",city: "北京市",city2: "北京市",},{name: "张二宝",amount: 200,date: "2019-05-04",city: "上海市",city2: "上海市",},{name: "王二丫",amount: 500,date: "2020-05-01",city: "深圳市",city2: "深圳市",},{name: "胡图图",amount: 1000,date: "2021-05-03",city: "广州市",city2: "广东省广州市",},{name: "张小龙",amount: 2000,date: "2022-05-03",city: "杭州市",city2: "浙江省杭州市",},];// copy 一份数据出来this.tableDataCopy = JSON.parse(JSON.stringify(this.tableData));},// 关闭条件tagconditionClose(index) {this.conditionList.splice(index, 1);this.customSearch(); //筛选数据},},mounted() {// 请求自定义筛选下拉框数据this.getCustomData();// 请求table数据this.search();},components: {customHeader,},
};
</script>
<style scoped lang='scss'>
// 占位,解决点击自己写的自定义筛选 会冒泡到排序
/deep/ .el-table__column-filter-trigger {display: none !important;
}
</style>

子组件

<template><!-- 注意:逻辑部分尽量不好写到这个组件内,因为这个组件是根据外面table循环创建的,在这里写逻辑会非常影响性能 --><div class="customHeader" @click.stop style="display: inline-block"><el-popoverplacement="bottom"title="查询条件"width="300"trigger="click"ref="popover"><!-- txt 文本 --><div v-if="item.conditionType == 'txt'"><el-inputv-model.trim="conditions.value1"placeholder="请输入查询内容"@keyup.native.enter="confirm()"></el-input></div><!-- scope 范围--><div v-else-if="item.conditionType == 'scope'"><el-inputstyle="width: 120px"v-model.trim="conditions.value1"placeholder="请输入条件1"></el-input>-<el-inputstyle="width: 120px"v-model.trim="conditions.value2"placeholder="请输入条件2"></el-input></div><!-- date 日期--><div v-else-if="item.conditionType == 'date'"><el-date-pickerv-model="conditions.value1"type="date"clearableplaceholder="开始时间"value-format="yyyy-MM-dd"></el-date-picker><el-date-pickerstyle="margin-top: 10px"v-model="conditions.value2"type="date"clearableplaceholder="结束时间"value-format="yyyy-MM-dd"></el-date-picker></div><!-- select 选择框--><div v-else-if="item.conditionType == 'select'"><el-selectv-model="conditions.value1"placeholder="请选择"style="width: 100%"clearable><el-optionv-for="(item, index) in selectList(item)":key="index":label="item.value":value="item.value"></el-option></el-select></div><!-- confirm 确定框--><div style="text-align: center"><el-button @click="confirm" type="primary" size="mini" class="confirm">确定</el-button></div><!-- label 标题显示--><spanslot="reference"onselectstart="return false"oncontextmenu="return false"class="label":class="{ labelColor: labelColorList.includes(item.prop) }">{{ column.label }} &nbsp;<i class="el-icon-arrow-down"></i></span></el-popover></div>
</template>
<script>
export default {name: "customHeader",// column 当前列数据,tableConfig 内数据,customParams 下拉框数据, labelColorList 正在使用的筛选条件props: ["column", "item", "customParams", "labelColorList"],data() {return {conditions: {value1: "",value2: "",},};},methods: {confirm() {if (!this.conditions.value1 && !this.conditions.value2) {return this.$message.warning("请选择筛选条件");}// 关闭popoverthis.$refs.popover.doClose();this.$emit("tableUpdate", {value: this.conditions, //所筛选的数据...this.item, //table 配置});},},computed: {selectList() {return function (data) {return this.customParams[data.conditionListName];};},},
};
</script>
<style scoped>
.confirm {margin-top: 10px;
}
/* 禁止双击选中文字 */
.label {-moz-user-select: none; /*火狐*/-webkit-user-select: none !important; /*webkit浏览器*/-ms-user-select: none; /*IE10*/-khtml-user-select: none; /*早期浏览器*/user-select: none;
}
.labelColor {color: #409eff;
}
</style>

肯定有写的不完美的地方,请指教

附录:手动实现自定义筛选后,点击下拉框被排序问题

element table手动实现自定义筛选(手动实现)相关推荐

  1. Element的Notification通知自定义样式手动关闭直接渲染带html格式的字符串

    效果图: 功能点1:弹窗需要自定义样式,例如实现滚动条展示多条数据 答:其实简单的自定义样式可以使用官网提供的:message 属性支持传入 HTML 片段 不过我用的是 createElement, ...

  2. element table 展开行 自定义展开方式与触发方式

    element官网并没有给我们自定义table行展开的自定义方式与自定义展开按钮,所以只能自己通过一些其他方法达到这个需求 直接上代码 <el-table ref="tableRef& ...

  3. Vue Element table表格实现表头自定义多类型动态筛选 , 目前10种筛选类型,复制即用

    一.效果图 目前10种筛选类型 看看是否是你需要的,本文可能有点长 ,我尽可能的给讲清楚,包括源码附上 二.无聊发言 点击当前行跳转 部分数据后缀追加图标 某列数据根据状态增加颜色标识 三.前言 实现 ...

  4. Validation校验参数-API、自定义、手动校验

    Validation校验参数-API.自定义.手动校验 Validation校验参数-API.自定义.手动校验 依赖 约束性注解 @Validated与@Valid的简单对比说明 Demo 校验 自动 ...

  5. element table批量删除_element ui 批量删除

    //这里做一个事件 checkbox发生改变时触发 修改 删除 data{ return { multipleSelection: [] //返回的是选中的列的数组集合 这里接收用户选中的id 默认放 ...

  6. element table v-for动态隐藏列

    element table v-for动态隐藏列 这个动态列是我项目中觉得比较好玩的一个功能,他列表不固定,后端数据库表也不固定,其实还有个高级筛选,这两个是配套使用的, <el-tablere ...

  7. Vxe-table表格自定义筛选

    vue2自定义类型 需求:需要搜索筛选复选框 在src/components新建FilterExtend.vue,内容如下 <template><div class="my ...

  8. element table 表格外input关键字搜索和多选

    需要用到:element Table自定义表头关键字搜索+element Table多选两个模块 https://element.eleme.cn/#/zh-CN/component/table  遇 ...

  9. 动态处理表格多行合并单元格、同时解决hover错乱问题 - Vue Element Table

    简介: el-table单元格合并,处理hover错乱问题,自定义底部合计栏. 如图所示: 源码(复制另存txt,修改.html直接运行) <!DOCTYPE html> <html ...

最新文章

  1. 理解人类世界的常识对于人工智能是一项挑战
  2. 2017计算机考研教材,【考研】2017计算机考研:四大科目参考书推荐
  3. linux shell 文件 第一行插入字符串
  4. CornerNet 测试:
  5. python计算器gui设计_python GUI模拟实现计算器
  6. linux软件包管理学习归档-2020-0624
  7. 怎么用计算机弹柯南,柯迷们的骚操作有哪些?用计算器弹柯南主题曲,自制缩小药丸...
  8. 一条视频涨粉百万,主角却不是人?!
  9. 挑战程序设计竞赛:三角形
  10. SMOTE算法原理 易用手搓小白版 数据集扩充 python
  11. hausaufgabe--python 22- Recurse
  12. 安焦的caoz和幻影的众人 过招
  13. CAD梦想画图中删除命令
  14. 服务器系统的功能,操作系统服务器主要功能
  15. Google AutoValue详解
  16. git常用命令和基本操作
  17. 我的大学(学习-上)
  18. 高并发下单/抢票问题处理
  19. 中国医学计算机成级别像杂志,中国医学计算机成像杂志
  20. 他们是我的父母 我能怎么办?

热门文章

  1. c语言获得本机mac地址,VC实现获取本机MAC地址的方法
  2. linux 6.5光驱是什么意思,centos 6.5 把光盘设置为本地yum源
  3. ShareTechnote系列LTE(13):上行链路数据传输调度-持续调度
  4. 影驰H610MK主板在MBR硬盘上安装系统(可用于安装WIN7)
  5. CES 2023:BOE京东方“屏实力”引领“屏之物联”新视界
  6. MB10M-ASEMI整流桥MB10M
  7. Java 文本检索神器 “正则表达式”
  8. Ajax请求不带上cookie的原因
  9. matlab求节点导纳矩阵,关于利用矩阵稀疏技术求解节点导纳矩阵的MATLAB编程
  10. 小米6 android 9氮os,360 N7和小米6X哪个好 360手机N7与小米6X区别对比