1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > element table手动实现自定义筛选(手动实现)

element table手动实现自定义筛选(手动实现)

时间:2022-11-18 11:37:54

相关推荐

element table手动实现自定义筛选(手动实现)

先看效果图

一、前言

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

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

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

txt 文本型 (就是input输入框)scope 范围型 (查询金额区间)date 时间型 (查询日期)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: "-05-02",city: "北京市",city2: "北京市",},{name: "张二宝",amount: 200,date: "-05-04",city: "上海市",city2: "上海市",},{name: "王二丫",amount: 500,date: "-05-01",city: "深圳市",city2: "深圳市",},{name: "胡图图",amount: 1000,date: "-05-03",city: "广州市",city2: "广东省广州市",},{name: "张小龙",amount: 2000,date: "-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>

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

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。