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

问题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>

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

Vue的Table组件可以通过添加一个全选框来实现全选功能。以下是如何实现vue table全选的步骤。 1. 首先,在Table组件中添加一个全选的列。可以使用一个表头的checkbox来表示全选功能。在表头的checkbox上绑定一个点击事件。 2. 在data中添加一个变量,用来记录全选的状态,例如`isAllSelected: false`。 3. 在表头checkbox的点击事件中,根据点击状态切换全选的状态。例如,如果选中了表头的checkbox,则设置`isAllSelected`为true;如果取消选中,则设置`isAllSelected`为false。 4. 在表格的每一行中,添加一个checkbox用来表示该行是否被选中。使用一个数组来记录每一行的选中状态。例如,可以使用`selectedRows: []`来记录选中的行。 5. 在行的checkbox上绑定一个点击事件,在点击事件中切换该行的选中状态。如果该行的checkbox选中,则将该行的数据加入到`selectedRows`数组中;如果取消选中,则将该行的数据从`selectedRows`数组中移除。 6. 在渲染表格数据时,根据每一行的选中状态来设置checkbox的选中状态。可以使用`:checked`绑定属性来动态设置checkbox是否选中。 7. 在全选的checkbox中,可以通过监听`isAllSelected`的变化来自动选中或取消选中所有行的checkbox。 通过上述步骤,就可以在Vue的Table组件中实现全选功能。当点击表头的全选checkbox时,会触发全选事件,自动选中或取消选中所有行的checkbox。在渲染表格时,根据每一行的选中状态来设置checkbox的选中状态。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值