vue中使用el-table组件进行分页多选,回显、切换分页记住上一页所勾选和取消的选项

需求:

1、table表格多选,并且切换分页之后能记住上一页的选项;
2、回显数据,切换分页之后再切换回来依然能回显数据;
3、点击选项,未保存数据,切换页面后再切换回来初始化数据勾选状态;
4、全选,取消全选数据正常变化。
5、使用了dialog来显示table
6、后台分页。

使用el-table:

1、el-table方法:select和select-alltoggleRowSelection和clearSelection
2、el-table-column类型:type="selection"
3、分页组件:Pagination(将el-pagination封装过一层)

代码:

逻辑代码说明在最下面。

<el-dialog
   title="产品列表"
   width="69%"
  :visible.sync="visible"
  :close-on-click-modal="false"
  :close-on-press-escape="false"
  :destroy-on-close="true"
  :before-close="handleClose"
>
  <el-divider></el-divider>
  <el-table
  	ref="multipleTable"
  	row-class-name="pointer"
    :data="productList.list"
    @select="handleSelectionChange"
    @select-all="handleAllChange"
  >
    <el-table-column type="selection" align="center" width="55" />
    <el-table-column label="方案状态">
      <template slot-scope="scope">{{ scope.row.schemaStatustext || '--' }}</template>
    </el-table-column>
    <el-table-column label="产品方案名称">
      <template slot-scope="scope">{{ scope.row.schemaName || '--' }}</template>
    </el-table-column>
  </el-table>
  <div style="text-align: right">
    <pagination
      v-show="productList.total > 0"
      :total="productList.total"
      :page.sync="listQueryPage1"
      :limit.sync="listQueryLimit1"
      @pagination="getQueryPages"
    />
  </div>
  <el-row>
    <el-button type="default" @click="exit">退出</el-button>
    <el-button type="primary" @click="save">保存</el-button>
  </el-row>
</el-dialog>
data() {
    return {
      productList:{},
      echoList: [],
      visible: false
    };
  },
// 以下方法在methods中

methods:{
    // 显示dialog框
    showproductsList() {
      this.dialogVisible = true;
      // 获取回显数据列表
      this.getchannelRelas();
      // 获取分页列表
      this.getQueryPages();
    },
    // 关闭dialog框
    exit() {
      // 清空未保存的勾选、取消状态
      this.$refs.multipleTable.clearSelection();
      this.visible = false;
    },
    // 点击dialog右上角关闭图标或者点击ESC按键,隐藏dialog框时触发。
    handleClose(down) {
      this.$refs.multipleTable.clearSelection();
      down();
    }
    // 分页获取table列表,每次切换页码时都会执行该方法
	getQueryPages() {
	  this.$store.dispatch('channel/querypageps', {
	      page: 1,
	      limit: 10,
	      queryCondition: {}
	    })
	    .then(res => {
	      const { status, data } = res;
	      if (status === 200) {
	        this.productList = { ...data };
	        this.$nextTick(() => {
	          this.productList.list.forEach(item => {
	            // 重点: 在当前分页列表中查询与回显数据是否有一致的id,一致则勾选数据回显
	            // toggleRowSelection(item, true):设置当前行数据为选中状态
	            if (this.echoList.includes(item.id)) {
	              this.$refs.multipleTable.toggleRowSelection(item, true);
	            }
	          });
	        });
	      }
	    });
	},
	// 获取回显数据
	getchannelRelas() {
	  this.$store.dispatch('channel/channelRelas', {
	      id: this.channelleaseId
	    })
	    .then(res => {
	      const {status, data } = res;
	      if (status === 200 && data) {
	        // 筛选回显数据的id,生成数组,根据id来勾选数据
	        this.echoList= data.map(item => item.id);
	      }
	    });
	},
    // 选择关联产品:打勾或取消
    handleSelectionChange(selecteds, row) {
      if (!this.echoList.includes(row.id)) {
        // 回显数据里没有本条,把这条加进来(选中)
        this.echoList.push(row.id);
      } else {
        // 回显数据里有本条,把这条删除(取消选中)
        this.echoList.forEach((id, index) => {
          if (id === row.id) {
            this.listId.splice(index, 1);
          }
        });
      }
    },
    // 全选、取消全选
    handleAllChange(selecteds) {
      if (selecteds.length > 0) {
        selecteds.forEach(item => {
          if (!this.echoList.includes(item.id)) {
            this.echoList.push(item.id);
          }
        });
      } else {
        this.productList.list.forEach(item => {
          this.echoList.forEach((id, index) => {
            if (id === item.id) {
              this.echoList.splice(index, 1);
            }
          });
        });
      }
    },
}

以上部分就是核心代码,理解流程逻辑,就能明白分页、多选、回显的真谛了。

回显数据:
显示dialog时获取echoList(回显数据)以及产品列表(productList)第一页数据。其实这里应该使用async和await方式,因为两个函数是异步操作,无法判断先后顺序,先不管这个。在获取productList后循环判断是否与echoList匹配,如果匹配则使用this.$refs.multipleTable.toggleRowSelection(item, true)方式勾选数据,当切换分页的时候还会继续执行以上的判断。回显数据就写完了。

单项勾选以及取消勾选,全选以及取消全选:
单项勾选操作方法:handleSelectionChange,当点击checkbox时,循环判断echoList中是否有当前行信息,若是没有,则说明是选中状态,push进echoList中;若是存在当前行信息,则说明是取消勾选,则将echoList中当前行id删除。

全选操作方法:handleAllChange,全选方法有一个参数selecteds,这是一个选中项数组,记录了有多少条选中项;当进行全选操作时,判断selecteds数组的length,若length>0,循环selecteds判断echoList数组中是否与selecteds中id匹配,若不匹配,则表示新增选中项,循环判断是为了去除重复项,还有一种简单的去除数组重复项的方法,使用Set:Array.from(new Set(this.echoList));若length===0,则代表取消勾选项,这时候一定要循环productList,判断echoList中的id是否与productList中的id是否匹配,若匹配,则删除取消项。

当前操作回显数据操作结合使用,则切换分页记住勾选取消状态便成功了。

关闭dialog框清除未保存过的状态
当勾选或取消勾选时,未进行保存,则关闭页面重新进来时,应当初始化勾选的状态,未保存过的状态不应该存在。则可以使用**this.$refs.multipleTable.clearSelection()**方法来初始化数据。

若有问题,随时欢迎。

### 解决 Element-UI `el-table` 中勾选状态的回显问题 为了实现 `el-table` 的框能够正确保存并恢复用户的勾选状态,可以采用如下解决方案: #### 设置表格列属性 定义带有择功能的表头时,设置 `type="selection"` 并启用保留已选项的功能。 ```html <el-table-column type="selection" :reserve-selection="true" width="40" align="center"></el-table-column> ``` 此配置允许即使页面刷新或分页变化后仍能记住择[^1]。 #### 初始化默认中的行 通过 JavaScript 来处理初始化阶段的数据加载完成后自动中特定记录的操作。这里的关键在于利用 Vue 组件生命周期钩子函数,在组件挂载完成之后执行逻辑操作来设定初始状态下哪些条目应该被标记为已中。 对于给定的例子来说,可以通过遍历两个不同的数组——一个是存储着所有待显示项目的列表 (`confList`);另一个则是用来指示那些项目应当预先处于定状态的身份标识符集合(`dpriceConfIdStr`)—以此找到匹配的对象实例,并调用 API 方法将其加入到当会话内的取队列里去。 具体做法是在获取到最新的数据源更新完毕后的时机点上(通常借助于 `$nextTick()`),再依次检查每一个对象是否存在于预设好的 ID 列表之中,一旦发现符合条件就立即触发对应的单个单元格级别的择事件。 以下是具体的代码片段展示如何实现这一点: ```javascript // 定义用于唯一识别每一行的方法 getRowKey(row) { return row.dpriceConfId; } mounted() { // 当组件渲染结束后才继续下面的动作 this.$nextTick(() => { // 对 dpriceConfIdStr 数组里的每个 id 执行查找与绑定动作 this.dpriceConfIdStr.forEach(vl => { const foundItem = this.confList.find(item => item.dpriceConfId === vl); if (foundItem !== undefined) { // 使用 toggleRowSelection 函数指定某一行应被中 this.$refs.multipleTable.toggleRowSelection(foundItem, true); } }); }); } ``` 上述代码确保了当页面初次加载或是重新加载时,先由用户做出的择不会丢失而是得以重现出来[^3]。 另外需要注意的是,如果存在交互行为比如点击按钮改变某些行的状态,则可以在相应的地方再次调用 `toggleRowSelection()` 或者其他相关接口来进行动态调整[^2]。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值