vue elementUI table 多頁(yè)選中 回顯的處理邏輯

效果
image.png

代碼

<template>
  <div class="lesson-main">
    <section class="lesson-body">
      <section class="lesson-body-left">
        <div class="filter-box">
          <span class="search-input-box">
            <el-input
              v-model="keyword"
              placeholder="請(qǐng)輸入關(guān)鍵詞搜索"
              prefix-icon="el-icon-search">
            </el-input>
          </span>
        </div>
        <div class="table-wrapper">
          <el-table class="table-border"
            ref="lessonTableRef"
            :data="lessonList"
            :row-key="(row)=>{ return row.classId}"
            @select="handleSelectionChange"
            @select-all="handleAllChange">
            <el-table-column
              width="80"
              type="selection"
              :reserve-selection="true">
            </el-table-column>
            <el-table-column prop="lessonTitle" label="名稱(chēng)" min-width="200">
              <template slot-scope="scope">
                <div class="lesson-info">
                  <p class="icon_course"></p>
                  <p class="title">{{ scope.row.classTitle }}</p>
                </div>
              </template>
            </el-table-column>
            <el-table-column prop="duration" label="時(shí)長(zhǎng)" min-width="120">
              <template slot-scope="scope">{{ scope.row.duration | handleDuration }}</template>
            </el-table-column>
            <el-table-column prop="" label="過(guò)期時(shí)間" min-width="120">
              <template slot-scope="scope">{{scope.row.expireTime ? scope.row.expireTime.slice(0, 10) : '-'}}</template>
            </el-table-column>
          </el-table>
          <div class="table-page">
            <p class="all-btn"
              :class="{
                disabled: !this.count
              }"
              @click="handleSelectAll()">全部篩選結(jié)果</p>
            <el-pagination
              style="text-align: right"
              background
              :total="count"
              :current-page="page"
              :page-size="pageSize"
              :page-sizes="pageSizesG"
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange"
              layout="sizes, prev, pager, next">
            </el-pagination>
          </div>
        </div>
      </section>
      <section class="lesson-body-right">
        <div class="choose-header">
          <p class="text">已選擇:{{chooseLessonList.length}}/{{count}}</p>
          <p class="close-btn"
            @click="handleClearAll()">清除所有</p>
        </div>
        <div class="choose-wrapper">
          <ul class="lesson-list draggable-list">
            <li class="lesson-item lesson-drag-btn"
              v-for="(info, i) in chooseLessonList"
              :key="`lesson${info.classId}`">
              <p class="icon_course"></p>
              <p class="title">{{info.classTitle}}</p>
              <p class="icon_close"
                @click.stop="handleClear(i)"></p>
            </li>
          </ul>
        </div>
      </section>
    </section>
    <section class="lesson-footer">
      <newElButton
        width='80px'
        btnType='cancel'
        @handleClick='handleLessonCancel()'
        >取消</newElButton>
      <newElButton
        class='ml20'
        width='80px'
        @handleClick='handleLessonSave()'
        >確定</newElButton>
    </section>
  </div>
</template>
<script>
import { getLessonList } from '@/api'

import Sortable from "sortablejs";
import newElButton from '@/components/elUI/newElButton'
export default {
  components: {
    newElButton
  },
  props: {
    selectList: {
      type: Array
    }
  },
  data () {
    return {
      keyword: '',
      count: 0,
      page: 1,
      pageSize: 10,
      lessonList: [], // 
      echoList: [], // 收集回顯用的數(shù)據(jù)
      chooseLessonList: [], // 實(shí)際保存的數(shù)據(jù)
    }
  },
  methods: {
    // 單項(xiàng)選擇:打勾或取消
    handleSelectionChange (selected, row) {
      if (!this.echoList.find(info => info.classId === row.classId)) {
        // 回顯數(shù)據(jù)里沒(méi)有本條,把這條加進(jìn)來(lái)(選中)
        this.echoList.push(row)
      } else {
        // 回顯數(shù)據(jù)里有本條,把這條刪除(取消選中)
        this.echoList.forEach((info, index) => {
          if (info.classId === row.classId) {
            this.echoList.splice(index, 1)
          }
        })
      }
      // 這里用于收集實(shí)際需要的數(shù)據(jù)數(shù)組
      this.chooseLessonList = this.echoList;
    },
    // 全選、取消全選(原理同上面的單選)
    handleAllChange (selected) {
      if (selected.length > 0) {
        // 多頁(yè)同時(shí)選中時(shí),先清除當(dāng)前頁(yè)數(shù)據(jù)
        this.lessonList.forEach((item) => {
          this.echoList.forEach((info, index) => {
            if (info.classId == item.classId) {
              this.echoList.splice(index, 1);
            }
          });
        });
        // 再記錄選中的數(shù)據(jù)
        selected.forEach((item) => {
          if (!this.echoList.find(info => info.classId == item.classId)) {
            this.echoList.push(item);
          }
        });
      } else {
        // 數(shù)據(jù)為空代表取消全選,清除當(dāng)前頁(yè)所有數(shù)據(jù)
        this.lessonList.forEach((item) => {
          this.echoList.forEach((info, index) => {
            if (info.classId == item.classId) {
              this.echoList.splice(index, 1);
            }
          });
        });
      }
      // 這里用于收集實(shí)際需要的數(shù)據(jù)數(shù)組
      this.chooseLessonList = this.echoList;
    },
    // 全選、取消全選
    handleSelectAll () {
      if (!this.count) {
        return
      }
      this.$refs.lessonTableRef.toggleAllSelection()
    },
    // 清除所有
    handleClearAll () {
      this.echoList = []
      // 這里用于收集實(shí)際需要的數(shù)據(jù)數(shù)組
      this.chooseLessonList = this.echoList
      this.$refs.lessonTableRef.clearSelection();
    },
    // 清除單個(gè)
    handleClear (i) {
      let delRow = this.chooseLessonList.splice(i, 1)
      // 回顯數(shù)據(jù)也要移除被刪數(shù)據(jù)
      this.echoList.forEach((info, index) => {
        if (info.classId == delRow[0]?.classId) {
          this.echoList.splice(index, 1)
        }
      })
      this.handleSelectTable()
    },
    handleLessonSave () {
      this.$emit('save', this.chooseLessonList)
    },
    handleLessonCancel () {
      this.$emit('cancel')
    },
    handleSizeChange(val) {
      this.page = 1
      this.pageSize = val
      this.fetchLessonList()
    },
    handleCurrentChange (val) {
      this.page = val
      this.fetchLessonList()
    },
    fetchLessonList() {
      let params = {
        keyword: this.keyword,
        currentPage: this.page,
        pageSize: this.pageSize
      }
      params = this.filterSearchInfo(params)
      getLessonList(params).then(res => {
        if (res.data.code === 200) {
          let data = res.data.data
          if (data) {
            this.count = +data.total
            if (data.list && data.list.length) {
              this.lessonList = data.list
            } else {
              this.lessonList = []
            }
            this.$nextTick(() => {
              this.handleSelectTable()
            })
          }
        }
      }).catch(err => {
        this.handleError(err)
      })
    },
    handleSelectTable () {
      // 所有取消選中
      this.$refs.lessonTableRef.clearSelection()
      // 表格回顯選中
      if (this.echoList && this.echoList.length) {
        this.echoList.forEach(info => {
          this.lessonList.forEach(row => {
            if (row.classId == info.classId) {
              this.$refs.lessonTableRef.toggleRowSelection(row, true)
            }
          })
        })
      }
    },
    // 開(kāi)啟拖拽(未生效需要找原因)
    initRowDrop () {
      const tbody = document.querySelector(".draggable-list");
      const _this = this;
      Sortable.create(tbody, {
        handle: ".lesson-drag-btn",
        onEnd({ newIndex, oldIndex }) {
          if (newIndex === oldIndex) return false;
          const currRow = _this.chooseLessonList.splice(oldIndex, 1)[0];
          _this.chooseLessonList.splice(newIndex, 0, currRow);
        },
      });
    }
  },
  filters: {
    handleDuration (val) {
      if (!val) {
        return '--'
      }
      val = Number(val)
      var hour = Math.floor(val / 3600)
      var min = Math.ceil((val % 3600) / 60)
      if (hour > 0 && min > 0) {
        return `${hour}小時(shí)${min}分`
      } else if (hour > 0 && min === 0) {
        return `${hour}小時(shí)`
      } else {
        return `${min}分`
      }
    }
  },
  watch: {
    chooseLessonList () {
      this.$nextTick(() => {
        this.initRowDrop()
      })
    }
  },
  created () {
    this.echoList = JSON.parse(JSON.stringify(this.selectList))
    this.chooseLessonList = JSON.parse(JSON.stringify(this.selectList))
    this.fetchLessonList()
  },
}
</script>
<style lang="stylus" scoped>
.lesson-main
  width 100%
  height calc(100vh - 55px)
  display flex
  flex-direction column
  position relative
  .lesson-body
    height calc(100% - 57px)
    display: flex
    .lesson-body-left
      width calc(100% - 258px)
      height 100%
      border-right 1px solid #E9EAED
      padded_box(border-box, 16px 20px)
      .filter-box
        width 100%
        display: flex
        align-items: center
      .table-wrapper
        width 100%
        height calc(100% - 48px)
        // display flex
        // flex-direction: column
        // justify-content: space-between
        margin-top 16px
        // .table-border.el-table
        //   flex none
        .lesson-info
          width 100%
          display: flex
          align-items: center
          .icon_course
            width 20px
            height 20px
            background: url('~assets/img/knowledge/icon_course@2x.png') no-repeat center/100%
          .title
            max-width calc(100% - 48px)
            height: 20px;
            line-height: 20px
            font-family:'PingFangSC-Regular';
            font-size: 14px;
            color: #5E5F66;
            margin:0 8px 0 4px
        .table-page
          display: flex
          justify-content: space-between
          align-items center
          .all-btn
            line-height 20px
            font-family: 'PingFangSC-Regular';
            font-size: 14px;
            color: #3377FE;
            padded_box(border-box, 4px 12px)
            cursor pointer
            margin-top 18px
            &.disabled
              cursor: not-allowed
    .lesson-body-right
      width 258px
      height 100%
      padded_box(border-box, 16px 20px)
      .choose-header
        width 100%
        display: flex
        justify-content: space-between
        align-items: center
        .text
          height: 20px;
          line-height 20px
          font-family: PingFangSC-Regular;
          font-size: 12px;
          color: #5E5F66;
        .close-btn
          height: 20px;
          line-height 20px
          font-family: PingFangSC-Regular;
          font-size: 12px;
          color: #9B9EA8;
          cursor pointer
      .choose-wrapper
        width 100%
        scroll()
        scroll-bar()
        height calc(100% - 36px)
        margin-top 16px
        .lesson-list
          display: flex
          flex-wrap: wrap
          .lesson-item
            display: flex
            align-items center
            height 32px
            line-height: 20px
            background: #F1F6FE
            padded_box(border-box, 6px 12px)
            border-radius: 4px
            margin 0 10px 10px 0
            cursor pointer
            .icon_course
              width 20px
              height 20px
              background: url('~assets/img/knowledge/icon_course@2x.png') no-repeat center/100%
            .title
              height: 20px;
              line-height: 20px
              font-family: 'PingFangSC-Regular';
              font-size: 12px;
              color: #303544;
              margin 0 12px 0 4px
            .icon_close
              width 16px
              height 16px
              background: url('~assets/img/icon_close@2x.png') no-repeat center/12px
              cursor: pointer
  .lesson-footer
    flex none
    text-align right
    padded_box(border-box, 12px 20px)
    border-top 1px solid #E9EAED
</style>
參考

原文地址:https://blog.csdn.net/Skty_ywh/article/details/126000082

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容