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里面,否则选中行高亮会有问题。

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页