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="getQuerypageps"
    />
  </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.getQuerypageps();
    },
    // 关闭dialog框
    exit() {
      // 清空未保存的勾选、取消状态
      this.$refs.multipleTable.clearSelection();
      this.visible = false;
    },
    // 点击dialog右上角关闭图标或者点击ESC按键,隐藏dialog框时触发。
    handleClose(down) {
      this.$refs.multipleTable.clearSelection();
      down();
    }
    // 分页获取table列表,每次切换页码时都会执行该方法
	getQuerypageps() {
	  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()**方法来初始化数据。

若有问题,随时欢迎。

你可能感兴趣的:(vue,el-table,分页,多选,回显)