首页 前端知识 Vue ElemnetUI 表格实现全选、反选、清空

Vue ElemnetUI 表格实现全选、反选、清空

2024-08-24 23:08:55 前端知识 前端哥 231 207 我要收藏

问题1

        当你在某页选择了数据,但是在切换页面后,之前选择的数据被清空了,这个时候,你需要在el-table标签上加上row-key属性以及在type="selection"的el-table-column标签上将reserve-selection置为true,如下图:

这样,你就可以解决上述的问题了,切换页面还能保留之前选择的数据。


问题2(全选)

         以下两张图 ,是我设计的一个简易的静态页面,以及其对应的代码

// element-ui  table  全选 反选  清空 展示
<template>
  <div class="w100 h100 f-dir">
    <div class="title">
      <span>表格全选/反选/清空</span>
    </div>
    <div class="content">
      <div class="btn">
        <el-button type="success" @click="click(1)">全选</el-button>
        <el-button type="primary" @click="click(2)">反选</el-button>
        <el-button type="warning" @click="click(3)">清空</el-button>
        <div class="btn-span">
          <span class="ml10"
            >已选<span>{{ selectList.length }}条</span></span
          >
          <span class="ml10"
            >总记录<span>{{ total }}条</span></span
          >
        </div>
      </div>
      <el-table
        :data="tablePage"
        ref="table"
        @selection-change="handleSelectionChange"
        :height="500"
        :row-key="row=>row.id"
      >
        <el-table-column type="selection" width="55" :reserve-selection='true'> </el-table-column>
        <el-table-column prop="name" label="姓名"></el-table-column>
        <el-table-column prop="age" label="年龄"></el-table-column>
        <el-table-column prop="sex" label="性别"></el-table-column>
      </el-table>
      <el-pagination
        style="height: 40px"
        class="mt15"
        background
        layout="prev, pager, next"
        :total="total"
        :page-size="page_size"
        :current-page.sync='page'
        @current-change="handleCurrentChange"
      >
      </el-pagination>
    </div>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      tableAll: [], //所有的数据
      tablePage: [], //某一页的数据
      selectList: [], //选中的数据
      page: 1,
      page_size: 25,
      total: 0,
    };
  },
  methods: {
    // 页数的切换
    handleCurrentChange(page) {
      console.log(page);
      this.page = page
      const startIndex = (page - 1) * this.page_size; // 计算起始索引位置
      const endIndex = startIndex + this.page_size; // 计算结束索引位置
      this.tablePage = JSON.parse(JSON.stringify(this.tableAll)).slice(startIndex,endIndex)
    },
    // 点击表格的选择框
    handleSelectionChange(val){
      this.selectList = val
    },
    click(num){
      // 全选
      if(num === 1){
        // this.tablePage.map(item=>this.$refs.table.toggleRowSelection(row,true))
        this.tableAll.map(row=>this.$refs.table.toggleRowSelection(row,true))

      }else if(num === 2){ //反选
        this.tableAll.map(row=>this.$refs.table.toggleRowSelection(row))
      }else{ //清空
        this.$refs.table.clearSelection()
      }
    }
  },
  mounted() {
    // 这里模拟获取全部数据
    for (let i = 0; i < 488; i++) {
      this.tableAll.push({
        id: i,
        name: `name${i}`,
        age: `age${i}`,
        sex: (i + Number(new Date().getTime())) % 3 === 0 ? "男" : "女",
      });
    }
    // 设置总条数
    this.total = this.tableAll.length;
    // 默认加载第一页数据
    this.handleCurrentChange(1)
  },
};
</script>

<style scoped>
.title {
  height: 20%;
  font-size: 30px;
  text-align: center;
  margin-top: 15px;
}
.btn {
  display: flex;
}
.btn-span {
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>

在这里,每一页的数据都是通过截取总数据,来进行渲染的(如果拿上面的代码能进行正常的全选、反选以及清空)。

但是在实际的开发中,会遇到每页的数据通过调接口储存在arr1,总数据通过调接口储存在arr2中,arr1和arr2其实是那种完全不一样的数组(即使arr1中的数据看起来是arr2的子集),这样和我以上的截取总数据存在本质上的区别(截取其实也是一种浅拷贝)。

在这种情况下,可以用JSON的方法,对总数据先进行深拷贝在截取,用来模拟调接口获取的数据

 handleCurrentChange(page) {
      console.log(page);
      this.page = page
      const startIndex = (page - 1) * this.page_size; // 计算起始索引位置
      const endIndex = startIndex + this.page_size; // 计算结束索引位置
      this.tablePage = JSON.parse(JSON.stringify(this.tableAll)).slice(startIndex,endIndex)
    },

这个时候点击全选,会出现以下的情况。

选中的数据数量是没错的,但是当前页的数据并没有被选中,但是在调到其他页在跳回当前页,这个数据就被选中了,这个咋解决呢?
现在没有实现的需求也就是点击全选后,当前页的选中显示没有显示出来,那么可以采取一点曲线救国的方法,如下

 this.tablePage.map(row=>this.$refs.table.toggleRowSelection(row,true)) //全选当前页
 const otherData = this.tableAll.filter(item => !this.tablePage.some(x=>x.id == item.id)) //找出剩余需要全选的数据
 otherData.map(row=>this.$refs.table.toggleRowSelection(row,true)) //将剩余数据进行全选

这样下来 全选的操作就没有问题了


 这样算来,如果采用这样一个曲线救国的方法,之前反选的代码就不能用了,直接上代码

let selectList = JSON.parse(JSON.stringify(this.selectList)) //这里储存的是之前选中的数据 通过下一行代码 会将this.selectList清空 所以得先存起来
this.$refs.table.clearSelection() //这里直接将之前选中的清空,直接拿selectList来判断那些需要选择,那些不选
this.tablePage.forEach(row => this.$refs.table.toggleRowSelection(row,!selectList.some(x => x.id == row.id))) // 反选当前页
const otherData = this.tableAll.filter(item => !this.tablePage.some(x=>x.id == item.id)) //找出剩余需要反选的数据
otherData.map(row=>this.$refs.table.toggleRowSelection(row,!selectList.some(x => x.id == row.id))) //将剩余数据进行反选


如上 就彻底解决的全选、反选、清空的操作了。以下是完整的代码

// element-ui  table  全选 反选  清空 展示
<template>
  <div class="w100 h100 f-dir">
    <div class="title">
      <span>表格全选/反选/清空</span>
    </div>
    <div class="content">
      <div class="btn">
        <el-button type="success" @click="click(1)">全选</el-button>
        <el-button type="primary" @click="click(2)">反选</el-button>
        <el-button type="warning" @click="click(3)">清空</el-button>
        <div class="btn-span">
          <span class="ml10"
            >已选<span>{{ selectList.length }}条</span></span
          >
          <span class="ml10"
            >总记录<span>{{ total }}条</span></span
          >
        </div>
      </div>
      <el-table
        :data="tablePage"
        ref="table"
        @selection-change="handleSelectionChange"
        :height="500"
        :row-key="row=>row.id"
      >
        <el-table-column type="selection" width="55" :reserve-selection='true'> </el-table-column>
        <el-table-column prop="name" label="姓名"></el-table-column>
        <el-table-column prop="age" label="年龄"></el-table-column>
        <el-table-column prop="sex" label="性别"></el-table-column>
      </el-table>
      <el-pagination
        style="height: 40px"
        class="mt15"
        background
        layout="prev, pager, next"
        :total="total"
        :page-size="page_size"
        :current-page.sync='page'
        @current-change="handleCurrentChange"
      >
      </el-pagination>
    </div>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      tableAll: [], //所有的数据
      tablePage: [], //某一页的数据
      selectList: [], //选中的数据
      page: 1,
      page_size: 25,
      total: 0,
    };
  },
  methods: {
    // 页数的切换
    handleCurrentChange(page) {
      this.page = page
      const startIndex = (page - 1) * this.page_size; // 计算起始索引位置
      const endIndex = startIndex + this.page_size; // 计算结束索引位置
      // this.tablePage = this.tableAll.slice(startIndex,endIndex)
      this.tablePage = JSON.parse(JSON.stringify(this.tableAll)).slice(startIndex,endIndex)
    },
    // 点击表格的选择框
    handleSelectionChange(val){
      console.log(1);
      this.selectList = val
    },
    click(num){
      // 全选
      if(num === 1){
        this.tablePage.map(row=>this.$refs.table.toggleRowSelection(row,true)) //全选当前页
        const otherData = this.tableAll.filter(item => !this.tablePage.some(x=>x.id == item.id)) //找出剩余需要全选的数据
        otherData.map(row=>this.$refs.table.toggleRowSelection(row,true)) //将剩余数据进行全选
      }else if(num === 2){ //反选
        let selectList = JSON.parse(JSON.stringify(this.selectList)) //这里储存的是之前选中的数据 通过下一行代码 会将this.selectList清空 所以得先存起来
        this.$refs.table.clearSelection() //这里直接将之前选中的清空,直接拿selectList来判断那些需要选择,那些不选
        this.tablePage.forEach(row => this.$refs.table.toggleRowSelection(row,!selectList.some(x => x.id == row.id))) // 反选当前页
        const otherData = this.tableAll.filter(item => !this.tablePage.some(x=>x.id == item.id)) //找出剩余需要反选的数据
        otherData.map(row=>this.$refs.table.toggleRowSelection(row,!selectList.some(x => x.id == row.id))) //将剩余数据进行反选
      }else{ //清空
        this.$refs.table.clearSelection()
      }
    }
  },
  mounted() {
    // 这里模拟获取全部数据
    for (let i = 0; i < 488; i++) {
      this.tableAll.push({
        id: i,
        name: `name${i}`,
        age: `age${i}`,
        sex: (i + Number(new Date().getTime())) % 3 === 0 ? "男" : "女",
      });
    }
    // 设置总条数
    this.total = this.tableAll.length;
    // 默认加载第一页数据
    this.handleCurrentChange(1)
  },
};
</script>

<style scoped>
.title {
  height: 20%;
  font-size: 30px;
  text-align: center;
  margin-top: 15px;
}
.btn {
  display: flex;
}
.btn-span {
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>

以上仅作为参考,只是用来给大家提供一个思路,如果觉得还阔以,点个赞,谢谢各位。

转载请注明出处或者链接地址:https://www.qianduange.cn//article/16749.html
标签
评论
发布的文章

安装Nodejs后,npm无法使用

2024-11-30 11:11:38

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!