element表格多选和单选、选中高亮处理、保存多页选中记录和翻页回显选中

环境:

  • element-ui@2.13.2

  • vue@2.6.6

示例:

1. 表格单选

  • 方案1
    <template>
    <div class="radio_page">
      <div class="selected_num">已选 {{selectedRow.name}}</div>
      <el-table
        :data="list"
        ref="table"
        :border="true"
        v-loading="loading"
        :row-class-name="rowClassName"
        @select="selectItem">
        <el-table-column
          type="selection"
          width="50">
        </el-table-column>
        <el-table-column
          prop="name"
          label="姓名">
        </el-table-column>
        <el-table-column
          prop="age"
          label="年龄">
        </el-table-column>
      </el-table>
      <el-pagination
        v-if="total"
        :total="total"
        :current-page.sync="pageNo"
        :page-size="limit"
        @current-change="handleCurrentChange">
      </el-pagination>
    </div>
    </template>
    <script>
    export default {
      data() {
        return {
          total: 100,
          pageNo: 1,
          limit: 10,
          selectedId: null, // 选中数据id
          selectedRow: {}, // 选中数据
          list: [], // 表格数据
          loading: false, // 加载标记
        }
      },
      methods: {
        init() {
          this.getList();
        },
        // 模拟接口获取数据
        getList() {
          if (this.loading) return;
          this.loading = true;
          setTimeout(() => {
            this.list = this.createList();
            this.loading = false;
            this.updateTableSelect();
          }, 1000);
        },
        // 生成数据
        createList() {
          const { pageNo, limit } = this;
          const res = [];
          const baseNum = limit * (pageNo - 1);
          for (let i = 0; i < limit; i++) {
            res.push({
              id: baseNum + i,
              name: '姓名' + (baseNum + i),
              age: baseNum + i
            })
          }
          return res;
        },
        // 接口返回数据后更新选中状态
        updateTableSelect() {
          this.$nextTick(() => {
            const list = this.list;
            const selectedRow = this.selectedRow;
            const needUpdate = list.find(item => {
              if (selectedRow && selectedRow.id == item.id) {
                return true;
              }
              return false;
            });
            if (needUpdate) {
              this.$refs.table.toggleRowSelection(needUpdate, true)
            }
          })
        },
        // 标记选中行增加特殊类
        rowClassName({row}) {
          const selectedRow = this.selectedRow;
          if (selectedRow && selectedRow.id == row.id) {
            return 'green';
          }
          return '';
        },
        // 单行切换选中状态处理
        selectItem(selection, row) {
          this.$refs.table.clearSelection()
          this.$nextTick(() => {
            this.$refs.table.toggleRowSelection(row, true);
            this.selectedRow = row;
          })
        },
        // 分页器页码变化
        handleCurrentChange(page) {
          this.pageNo = page;
          this.getList();
        },
      },
      created() {
        this.init();
      },
    }
    </script>
    <style lang="stylus">
    .radio_page{
      .green{
        background-color: #ddf7dd;
      }
      .el-table__header .el-checkbox{
        display none
      }
    }
    </style>
    
  • 方案2
    <template>
    <div class="radio_page">
      <div class="selected_num">已选 {{selectedRow.name}}</div>
      <el-table
        :data="list"
        ref="table"
        :border="true"
        v-loading="loading"
        :row-class-name="rowClassName">
        <el-table-column label="" align="center" width="50">
          <template scope="scope">
            <el-radio :label="scope.row.id" v-model="selectedId" @change.native="selectItem(scope.row)"></el-radio>
          </template>
        </el-table-column>
        <el-table-column
          prop="name"
          label="姓名">
        </el-table-column>
        <el-table-column
          prop="age"
          label="年龄">
        </el-table-column>
      </el-table>
      <el-pagination
        v-if="total"
        :total="total"
        :current-page.sync="pageNo"
        :page-size="limit"
        @current-change="handleCurrentChange">
      </el-pagination>
    </div>
    </template>
    <script>
    export default {
      data() {
        return {
          total: 100,
          pageNo: 1,
          limit: 10,
          selectedId: null, // 选中数据
          selectedRow: {}, // 选中数据
          list: [], // 表格数据
          loading: false, // 加载标记
        }
      },
      methods: {
        init() {
          this.getList();
        },
        // 模拟接口获取数据
        getList() {
          if (this.loading) return;
          this.loading = true;
          setTimeout(() => {
            this.list = this.createList();
            this.loading = false;
          }, 1000);
        },
        // 生成数据
        createList() {
          const { pageNo, limit } = this;
          const res = [];
          const baseNum = limit * (pageNo - 1);
          for (let i = 0; i < limit; i++) {
            res.push({
              id: baseNum + i,
              name: '姓名' + (baseNum + i),
              age: baseNum + i
            })
          }
          return res;
        },
        // 标记选中行增加特殊类
        rowClassName({row}) {
          const selectedRow = this.selectedRow;
          if (selectedRow && selectedRow.id == row.id) {
            return 'green';
          }
          return '';
        },
        // 单行切换选中状态处理
        selectItem(row) {
          this.selectedRow = row;
        },
        // 分页器页码变化
        handleCurrentChange(page) {
          this.pageNo = page;
          this.getList();
        },
      },
      created() {
        this.init();
      },
    }
    </script>
    <style lang="stylus">
    .radio_page{
      .green{
        background-color: #ddf7dd;
      }
      .el-radio__label{
        display: none;
      }
    }
    </style>
    

2. 表格多选

<template>
<div class="check_page">
  <div class="selected_num">已选 {{selection.length}} 人</div>
  <el-table
    :data="list"
    ref="table"
    :border="true"
    v-loading="loading"
    :row-class-name="rowClassName"
    @select="selectItem"
    @select-all="selectAll"
    @selection-change="selectionChange">
    <el-table-column
      type="selection"
      width="50">
    </el-table-column>
    <el-table-column
      prop="name"
      label="姓名">
    </el-table-column>
    <el-table-column
      prop="age"
      label="年龄">
    </el-table-column>
  </el-table>
  <el-pagination
    v-if="total"
    :total="total"
    :current-page.sync="pageNo"
    :page-size="limit"
    @current-change="handleCurrentChange">
  </el-pagination>
</div>
</template>
<script>
export default {
  data() {
    return {
      total: 100,
      pageNo: 1,
      limit: 10,
      selection: [], // 选中数据
      list: [], // 表格数据
      loading: false, // 加载标记
      selectRow: new Map(), // 标记当前选中行
    }
  },
  methods: {
    init() {
      this.getList();
    },
    // 模拟接口获取数据
    getList() {
      if (this.loading) return;
      this.loading = true;
      setTimeout(() => {
        this.list = this.createList();
        this.updateTableSelect();
        this.loading = false;
      }, 1000);
    },
    // 生成数据
    createList() {
      const { pageNo, limit } = this;
      const res = [];
      const baseNum = limit * (pageNo - 1);
      for (let i = 0; i < limit; i++) {
        res.push({
          id: baseNum + i,
          name: '姓名' + (baseNum + i),
          age: baseNum + i
        })
      }
      return res;
    },
    // 接口返回数据后更新选中状态
    updateTableSelect() {
      const selection = this.selection;
      if (!selection.length) return;
      this.$nextTick(() => {
        const list = this.list;
        const selectionMap = new Map();
        selection.forEach(item => {
          selectionMap.set(item.id, 1);
        });
        const needUpdate = list.filter(item => {
          if (selectionMap.has(item.id)) {
            return true;
          }
          return false;
        });
        needUpdate.forEach(item => {
          this.$refs.table.toggleRowSelection(item, true)
        });
      })
    },
    // 标记选中行增加特殊类
    rowClassName({row}) {
      const selectRow = this.selectRow;
      if (selectRow.has(row.id)) {
        return 'green';
      }
      return '';
    },
    // 单行切换选中状态处理
    selectItem(selection, row) {
      const selected = selection.find(item => item.id == row.id);
      if (selected) {
        this.selection = [ ...this.selection, row ];
      } else {
        this.selection = this.selection.filter(item => item.id != row.id)
      }
    },
    // 全选、全取消处理
    selectAll(newSelected) {
      if (newSelected.length == 0) {
        const cancelMap = new Map();
        this.list.forEach(item => {
          cancelMap.set(item.id, item);
        });
        const newSelected = this.selection.filter(item => {
          if (cancelMap.has(item.id)) {
            return false;
          }
          return true;
        });
        this.selection = [...newSelected];
      } else {
        const selectedMap = new Map();
        newSelected.forEach(item => {
          selectedMap.set(item.id, item);
        });
        const oldSelected = this.selection.filter(item => {
          if (selectedMap.has(item.id)) {
            return false;
          }
          return true;
        })
        this.selection = [...oldSelected, ...newSelected];
      }
    },
    // 选中状态变化,只会记录当前页,因此用于生成当前页选中行数据
    selectionChange(selection) {
      const newMap = new Map();
      selection.forEach(item => {
        newMap.set(item.id, item)
      });
      this.selectRow = newMap;
    },
    // 分页器页码变化
    handleCurrentChange(page) {
      this.pageNo = page;
      this.getList();
    },
  },
  created() {
    this.init();
  },
}
</script>
<style lang="stylus">
.check_page{
  .green{
    background-color: #ddf7dd;
  }
}
</style>
注意:

更新选中状态都是放到了$nextTick里面,否则选中行高亮会有问题。

可以通过设置表格数据的 `selected` 属性来实现多选数据回显。假设后端返回的数据中包含一个 `selectedIds` 数组,表示已选中数据的 ID,可以先遍历表格数据,将每条数据的 `selected` 属性设置为 `selectedIds` 数组中是否包含该条数据的 ID,然后在表格上添加一个 `@selection-change` 事件监听器,当用户手动勾选或取消勾选表格中的数据时,将新的选中数据的 ID 存入 `selectedIds` 数组中。 以下是一个示例代码,假设表格数据包含 `id` 和 `name` 两个字段: ```html <template> <el-table :data="tableData" @selection-change="handleSelectionChange" :select-on-indeterminate="false" :default-sort="{prop: 'id', order: 'ascending'}" :row-key="row => row.id" v-loading="loading"> <el-table-column type="selection" width="55"></el-table-column> <el-table-column prop="id" label="ID" sortable></el-table-column> <el-table-column prop="name" label="Name" sortable></el-table-column> </el-table> </template> <script> export default { data() { return { loading: false, tableData: [] } }, methods: { async fetchData() { this.loading = true; const response = await fetch('/api/data'); const data = await response.json(); this.tableData = data.map(item => ({ ...item, selected: false })); const selectedIds = data.filter(item => item.selected).map(item => item.id); this.tableData.forEach(item => { item.selected = selectedIds.includes(item.id); }); this.loading = false; }, handleSelectionChange(selection) { const selectedIds = selection.map(item => item.id); this.tableData.forEach(item => { item.selected = selectedIds.includes(item.id); }); } }, mounted() { this.fetchData(); } } </script> ``` 在上面的示例代码中,`fetchData` 方法通过 AJAX 请求获取后端数据,并将每条数据的 `selected` 属性初始化为 `false`。然后遍历后端返回的数据,将已选中数据的 `selected` 属性设置为 `true`。在表格上添加了一个 `selection-change` 事件监听器,当用户手动勾选或取消勾选表格中的数据时,将选中数据的 ID 存入 `selectedIds` 数组中,并遍历表格数据,将新的选中数据的 ID 存入 `selectedIds` 数组中。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值