当前位置:   article > 正文

element表格通过computed计算属性实现分页+filter方法实现搜索+表格分页的勾选功能及换页后显示已勾选项_el-table的filter支持分页吗

el-table的filter支持分页吗

前言

在el-element的标签里的tableData数据过多时,会导致表格页面操作卡顿。为解决这一问题,有以下解决方法:

分页加载: 将大量数据进行分页,并且只在用户需要时加载当前页的数据,可以减轻页面的数据负担。可以使用像 Element UI 提供的分页组件来实现分页加载功能。
虚拟滚动: 对于大量数据的列表展示,可以考虑使用虚拟滚动技术,只渲染当前可见区域的数据,而不是直接渲染所有数据。Element UI 的 Table 组件也支持虚拟滚动,可以通过相应的配置开启虚拟滚动功能。可参考虚拟滚动其它博主的文章
数据筛选和搜索: 提供数据筛选和搜索功能,让用户可以根据条件快速定位到需要的数据,减少不必要的数据展示。
服务端优化: 如果数据来源于服务端,可以在服务端对数据进行分页、压缩等处理,以减少前端页面加载的数据量。
组件优化: 检查页面中其他组件的性能表现,确保没有其他组件或代码导致页面性能下降。
前端性能优化: 考虑对前端代码进行性能优化,比如减少不必要的重复渲染、减少对大数据量的循环操作等。

效果展示

表格分页+搜索+勾选

代码分析

数据结构:

created () {
    // 模拟生成大量数据
    for (let i = 0; i < 1000; i++) {
      this.tableData.push({
        date: '2023-11-28',
        name: '用户' + i,
        age: i + '岁',
        ID: i
        // 其他字段
      });
    }
  },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

data:

tableData: [], // 原始数据
currentPage: 1, // 当前页码
pageSize: 10, // 每页显示的数量
searchText: ‘’, // 搜索的文本
filteredData: [], // 搜索后的数据
multipleSelection: [],//已勾选的项

分页功能

首先,在computed中,使用displayData计算属性来根据当前页码和每页数量筛选出要显示的数据。在el-table标签中绑定displayData:<el-table :data="displayData"></el-table>

通过computed属性,我们可以定义根据响应式数据计算的属性,并在模板中使用。Vue会自动追踪依赖关系,当依赖的响应式数据发生变化时,computed属性会重新计算其值。

computed: {
    // 根据当前页码和每页数量计算显示的数据
    displayData () {
      const startIndex = (this.currentPage - 1) * this.pageSize;
      const endIndex = startIndex + this.pageSize;
      return this.tableData.slice(startIndex, endIndex);
    },
  },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

其次,在methods中,handleSizeChange方法用于处理改变每页显示数量的事件,handleCurrentChange方法用于处理改变当前页码的事件。

// 改变每页显示的数量时触发
handleSizeChange(newSize) {
      this.pageSize = newSize;
      this.currentPage = 1; // 重置当前页码为第一页
},
// 改变当前页码时触发
handleCurrentChange(newPage) {
      this.currentPage = newPage;
},
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

最后,在mounted中,我们假设通过某种方式获取了原始数据,并将其赋值给tableData数组,若是调用接口,则在调用接口将获取的数据赋值给tableData数组即可。这里示例是用的json数据。

data () {
    return {
      tableData: jsondata,//方法一:使用示例数据进行演示,将json数据赋值给tableData数组
    };
},
mounted() {
    // 方法二:实际情况下可以通过接口请求或其他方式获取数据
    // 假设tableData是从后端获取的原始数据
    this.searchFun();
},
methods: {
	searchFun(){
		//......调用接口
		.then((res) => {this.tableData = res.obj;//将数据赋值给tableData})
		.catch((err) => {console.log("err",err);})
	},
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

这样,当用户改变每页显示数量或当前页码时,表格会自动根据新的参数重新渲染显示数据,同时Element UI的分页组件也会更新页码和显示的数据数量

过滤数据功能

1、在data中,添加了filteredData用于存储搜索后的数据,searchText用于保存搜索的文本。

searchText: '', // 搜索的文本
filteredData: [], // 搜索后的数据
  • 1
  • 2

2、在computed中,修改了displayData计算属性,使用filteredData进行分页显示。

computed: {
    displayData () {
      // 根据当前页码和每页数量计算显示的数据
      const startIndex = (this.currentPage - 1) * this.pageSize;
      const endIndex = startIndex + this.pageSize;
      return this.filteredData.slice(startIndex, endIndex);
    },
},
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

3、在mounted钩子中,初始化了tableData和filteredData,并将它们设置为示例数据。你可以根据实际情况从后端获取数据。
4、在methods中,添加了searchTextFun 方法来根据搜索文本过滤数据,并重置当前页码为第一页。若是在调用接口方法获取数据后调用searchTextFun即可。这里用的是name字段,可视情况改变:item.name.includes(this.searchText)
.filter()方法直达站

mounted () {
    this.filteredData = this.tableData;
    this.searchTextFun();
},
methods: {
    // 根据搜索文本过滤数据
    searchTextFun () {
      this.filteredData = this.tableData.filter(item =>
        item.name.includes(this.searchText)
      );//过滤数据
      this.currentPage = 1; // 重置当前页码为第一页
    },
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

5、在watch中,监听searchText的变化,并在变化时执行搜索操作。

watch: {
    searchText () {
      // 监听搜索文本变化,执行搜索操作
      this.searchTextFun();
    },
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这样,当用户输入搜索文本并提交时,表格会根据搜索结果显示相应的数据,并自动根据新的参数重新渲染分页组件。

多选功能

el-table自带的select和select-all事件,并通过ref调用对应表格元素的toggleRowSelection方法实现勾选项,以下是官网api的说明:
在这里插入图片描述

1、select事件 - 用户勾选每项的复选框时触发的逻辑

arguments 对象是一个类数组对象,它包含了函数参数的值以及一些有用的属性和方法。当函数被调用时,arguments 对象会自动被创建,并且可以在函数内部使用。

这里的@select="tableHandleSelect"方法被调用时传递了两个参数(list和item),则 arguments 对象的第一个元素就是第一个参数(list),第二个元素就是第二个参数(item),依此类推。我们可以通过下标来访问 arguments 对象中的各个参数,也可以直接使用参数list和item。
并且利用list.includes(item)来判断当前用户是点击勾选复选框还是取消复选框,若是勾选,则返回为true;否则为false。
最后使用了箭头函数和filter()方法,通过筛选条件item.ID !== arguments[1].ID,创建一个新的数组存储所有已勾选的数组,其中不包含要删除(取消复选框)的对象。

 // 表格的select方法
    tableHandleSelect (list, item) {
      console.log("list", list);
      console.log("item", item);
      console.log("arguments", arguments);
      if (list.includes(item)) {//勾选
        console.log('勾选arguments[0]', arguments[0]);
        this.multipleFun(arguments[0]);// 调用勾选复选框的方法
      } else {//取消勾选
        this.multipleSelection = this.multipleSelection.filter(item => item.ID !== arguments[1].ID);
      }
      console.log("已勾选数组multipleSelection:", this.multipleSelection);
    },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在这里插入图片描述
一下代码为补充代码,勾选复选框的逻辑和去重逻辑

// 勾选复选框的方法
    multipleFun (val) {
      if (this.multipleSelection.length) {
        var templist = [];
        for (var i in this.multipleSelection) {
          templist.push(this.multipleSelection[i]);
          if (val.length) {
            for (var j in val) {
              templist.push(val[j]);
            }
          }
        }
        this.multipleSelection = [];
        this.multipleSelection = JSON.parse(JSON.stringify(templist))
      } else {
        for (var z in val) {
          this.multipleSelection.push(val[z]);
        }
      }
      this.multipleSelection = this.removeDuplicatesV2(this.multipleSelection);//去重
    },
// 去重方法
    removeDuplicatesV2 (array) {
      const res = new Map()
      return array.filter((item) => !res.has(item.ID) && res.set(item.ID, 1))
    },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

2、select-all事件 - 当用户一键点击表头全选时的逻辑

这里需要考虑两个方向,一个是当前页表格的点击全勾选,一个是当前页表格的点击全部取消勾选。突破点就是根据参数selection,根据输出可以发现点击全选时它返回的是一个与pageSize相同长度的数组,反之则是个空数组。
通过@select-all="allHandleSelect"方法把对应页数中所有数据全部勾选,譬如,当前为第一页10条数据,点击表头的全选时,第一页的全部十条都被勾选中;再次点击取消全选时,将已勾选数据与当前页所有数据ID进行对比返回一个不相同ID的新数组对象。

// 全选
    allHandleSelect (selection) {
      console.log("selection", selection);
      if (selection.length) {//点击全选
        this.multipleFun(selection);
      } else {//点击取消全选 移除multipleSelection数组中与当前页数据相同ID的元素
        console.log("displayData", this.displayData);//当前页的所有数据
        this.multipleSelection = this.multipleSelection.filter(item => !this.displayData.some(sel => sel.ID === item.ID));
      }
      console.log("全选的multipleSelection", this.multipleSelection);
    },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

全部代码

<template>
  <div class="textbox-class">
    <div class="topbox-class">
      <el-input placeholder="搜索姓名"
                prefix-icon="el-icon-search"
                v-model="searchText"
                class="mleft-class searchinput-class">
      </el-input>
      <div class="mleft-class">
        您已勾选{{multipleSelection.length}}</div>
    </div>
    <div class="mainbox-class">
      <el-table :data="displayData"
                stripe
                border
                :header-cell-style="{background:'rgb(113 167 228)',color:'white'}"
                @select="tableHandleSelect"
                @select-all="allHandleSelect"
                ref="tableRef"
                highlight-current-row
                height="520"
                style="width: 50%">
        <el-table-column type="selection"
                         fixed="left"
                         width="50"></el-table-column>
        <el-table-column prop="date"
                         label="日期">
        </el-table-column>
        <el-table-column prop="name"
                         label="姓名">
        </el-table-column>
        <el-table-column prop="age"
                         label="年龄">
        </el-table-column>
      </el-table>
    </div>
    <div class="botbox-class">
      <el-pagination @size-change="handleSizeChange"
                     @current-change="handleCurrentChange"
                     :current-page="currentPage"
                     :page-sizes="[10,20,30,40,50]"
                     :page-size="pageSize"
                     layout="total, sizes, prev, pager, next, jumper"
                     :total="tableData.length"></el-pagination>
    </div>
  </div>
</template>

<script>
export default {
  data () {
    return {
      tableData: [], // 这里存放大量数据的数组
      filteredData: [], // 搜索后的数据
      currentPage: 1, // 当前页码
      pageSize: 10, // 每页显示的数量
      searchText: '', // 搜索的文本
      multipleSelection: [],//已勾选的项
    };
  },
  created () {
    // 模拟生成大量数据
    for (let i = 0; i < 1000; i++) {
      this.tableData.push({
        date: '2023-11-28',
        name: '用户' + i,
        age: i + '岁',
        ID: i
        // 其他字段
      });
    }
  },
  computed: {
    displayData () {
      // 根据当前页码和每页数量计算显示的数据
      const startIndex = (this.currentPage - 1) * this.pageSize;
      const endIndex = startIndex + this.pageSize;
      return this.filteredData.slice(startIndex, endIndex);
    },
  },
  mounted () {
    this.filteredData = this.tableData;
    this.searchTextFun();
  },
  methods: {
    // 改变每页显示的数量时触发
    handleSizeChange (newSize) {
      this.pageSize = newSize;
      this.currentPage = 1; // 重置当前页码为第一页
      this.$nextTick(() => {
        this.toggleSelection();
      });
    },
    // 改变当前页码时触发
    handleCurrentChange (newPage) {
      this.currentPage = newPage;
      this.$nextTick(() => {
        this.toggleSelection();
      });
    },
    // 根据搜索文本过滤数据
    searchTextFun () {
      this.filteredData = this.tableData.filter(item =>
        item.name.includes(this.searchText)
      );
      this.currentPage = 1; // 重置当前页码为第一页
      this.toggleSelection();
    },
    // 表格的select方法
    tableHandleSelect (list, item) {
      console.log("list", list);
      console.log("item", item);
      console.log("arguments", arguments);
      var val = arguments[0];//勾选的数据,array
      if (list.includes(item)) {//勾选时做的事
        console.log('勾选arguments[0]', arguments[0]);
        this.multipleFun(arguments[0]);
      } else {
        //取消勾选时做的事,arguments[1]是当前取消勾选的项
        this.multipleSelection = this.multipleSelection.filter(item => item.ID !== arguments[1].ID);
      }
      console.log("已勾选数组multipleSelection:", this.multipleSelection);
    },
    // 全选
    allHandleSelect (selection) {
      console.log("selection", selection);
      if (selection.length) {//点击全选
        this.multipleFun(selection);
      } else {//点击取消全选 移除multipleSelection数组中与当前页数据相同ID的元素
        console.log("displayData", this.displayData);//当前页的所有数据
        this.multipleSelection = this.multipleSelection.filter(item => !this.displayData.some(sel => sel.ID === item.ID));
      }
      console.log("全选的multipleSelection", this.multipleSelection);
    },
    // 勾选复选框的方法
    multipleFun (val) {
      if (this.multipleSelection.length) {
        var templist = [];
        for (var i in this.multipleSelection) {
          templist.push(this.multipleSelection[i]);
          if (val.length) {
            for (var j in val) {
              templist.push(val[j]);
            }
          }
        }
        this.multipleSelection = [];
        this.multipleSelection = JSON.parse(JSON.stringify(templist))
      } else {
        for (var z in val) {
          this.multipleSelection.push(val[z]);
        }
      }
      this.multipleSelection = this.removeDuplicatesV2(this.multipleSelection);
    },
    // 去重方法
    removeDuplicatesV2 (array) {
      const res = new Map()
      return array.filter((item) => !res.has(item.ID) && res.set(item.ID, 1))
    },
    // 默认勾上已选的项
    toggleSelection () {
      if (this.multipleSelection.length == 0) {
        return;
      }
      this.$nextTick(() => {
        this.multipleSelection.forEach(item => {
          for (var i of this.displayData) {
            if (item.ID == i.ID) {
              this.$refs.tableRef.toggleRowSelection(i, true)
            }
          }
        })
      })
    },
  },
  watch: {
    searchText () {
      // 监听搜索文本变化,执行搜索操作
      this.searchTextFun();
    },
  }
};
</script>

<style scoped>
.textbox-class {
  width: 100%;
  height: 100%;
}
.topbox-class {
  height: 5%;
  display: flex;
  align-items: center;
  margin-left: 0.5rem;
}
.mainbox-class {
  height: 55%;
}
.botbox-class {
  height: 3%;
}
.searchinput-class {
  width: 20%;
}
</style> 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/103102?site
推荐阅读
相关标签
  

闽ICP备14008679号