基于vue Element-ui的el-table多选框

文章记录大概业务解决过程

  • el-table的多选只能选择当前页,不能记录选中状态
  • 业务需求需要点击全选记录所有页的选中状态,记录当前的选择项
  • 1.直接在el-table type="selection"功能上修改
  • 优点:利用el-table的多选功能实现 this.$refs.multipleTable.toggleAllSelection()
  • 缺点:实现中覆盖el-table多选功能,导致重复依赖
    template: 
     "multipleTable" :data="tableData" 
      @selection-change="changeFun"
      @select="selectMemoryFn"
      @select-all="selectAll">
      "55"
        label="213"
        type="selection"
        class-name='selection-self' // 为了操作dom
        >
      
     
    js:
    data () {
        return {
            tableData: [],
            indeterminate: false,
            multipleSelection: [], // 选中的数据二维数组
            ids: [], // 选中的数据id数组
            selectAllChk: false, // 是否全选
        }
    }
    changeFun (val) { // 保存已选数据id到数组,供后续操作(与分页记忆无关)
      this.$nextTick(() => {
        let ids = []
        this.multipleSelection.forEach(L => L.forEach(M => ids.push(M.projectBaseId)))
        this.ids = ids
        console.log(this.ids.length, 'inder')
        if (this.allTableData.length !== this.ids.length && this.ids.length) {
          this.indeterminate = true
        } else {
          this.indeterminate = false
        }
        // 全选
        if (this.ids.length === this.allTableData.length) {
          this.selectAllChk = true
        }
        this.getChkClassName()
      })
    },
    selectAll (selection) { // 全选切换方法
      // 改变el-table
      let page
      if (this.allTableData) {
        page = this.allTableData.length / this.dataForBE.pageSize
      }
      console.log(this.ids.length, 'all')
      if (!this.ids.length || (this.indeterminate && this.ids.length)) { // 全选
        for(let i = 0; i < page; i++){
          this.multipleSelection[i] = this.allTableData.slice((i)*10 ,(i + 1)*10)
        }
        console.log(selection.length, 'leng')
        // 条件:有选中长度 
        if (this.indeterminate && this.ids.length && !selection.length) {
          this.setCurrent()
        }
        this.getChkClassName()
        this.selectAllChk = true
        this.indeterminate = false
      } else { // 全不选
        for(let i = 0; i < page; i++){
          this.multipleSelection[i] = []
        }
        this.selectAllChk = false
        this.indeterminate = false
      }
      console.log(this.multipleSelection, 'this.multipleSelection')
    },
    selectMemoryFn (val, row) { // 设置分页记忆二位数组方法
      // 注意:val 传过来默认为数组类型 ,row 为 Object(当前选择数据对象)
      let currentArr = this.multipleSelection[this.currentPage - 1] // 当前分页对应数组
      if (!currentArr) {
        this.multipleSelection[this.currentPage - 1] = val // 不存在这个二维数组,则创建这个二位数组
      } else { // 存在
        if (val.includes(row)) { // 选中
          this.multipleSelection[this.currentPage - 1] = val
          // 循环
        } else { // 取消
          currentArr.forEach(item => {
            if (item.projectBaseId === row.projectBaseId) {
              delete currentArr[currentArr.indexOf(item)]
            }
          })
        }
      }
    },
    selectMemoriedDataFn () { // 分页记忆自动选中方法
      if (this.selectAllChk && !this.multipleSelection[this.currentPage - 1]) {
        this.$refs.multipleTable.toggleAllSelection()
      }
      if (this.allTableData.length !== this.ids.length && this.ids.length) {
        this.indeterminate = true
      }
      this.setCurrent()
      // 选择框样式
      this.getChkClassName()
    },
    setCurrent () {
      let currentArr = this.multipleSelection[this.currentPage - 1]  // 当前分页对应被选中数据
      if (currentArr && currentArr.length) { // 存在则继续执行
        let tempRowsIDs = this.tableData.map(L => L.projectBaseId) // 当前分页被选中数据的id集合
        currentArr.forEach((item, index) => { // 遍历当前分页被选中数据
          if (tempRowsIDs.includes(item.projectBaseId)) { // id匹配上,则选中
            this.$refs.multipleTable.toggleRowSelection(this.tableData[tempRowsIDs.indexOf(item.projectBaseId)])
          }
        })
      }
    },
复制代码
  • 代码可能不完善
  • 2.自己每行中加el-checkbox ,表头用renderHeader
  • 优点:不混合el-table中的多选功能,单独实现
  • 缺点:本是利用el-table却单独实现
template
    el-table-column :render-header="renderHeader" width="55">
            
            
          
 // 点击到了和表格一样多
    enoughLen () {
      let sumNum = 0
      // let num = Math.ceil(this.totalCount/this.dataForJava.pageSize)
      // console.log(this.selectionPage, 'this.selectionPageq')
      this.selectionPage.forEach((itemSelect, selectIndex) => {
        if (itemSelect.status === '0') {
          sumNum += itemSelect.length
          this.allFlagAfter = false
          this.indeterminate = true
        }
      })
      if (sumNum === this.totalCount) {
        this.selectAllFlag = true
        this.allFlagAfter = true
        this.indeterminate = false
      } else if (sumNum === 0) { // 全部没有
        this.selectAllFlag = false
        this.allFlagAfter = true
        this.indeterminate = false
      }
    },
    // 选中每一个多选框
    selectChange (selection, selectionIndex) {
      // 筛选数据
      this.fliterData(selection)
      // 记录选中和取消选中
      this.selectionPage[this.dataForJava.page - 1] = this.currentSelection
      this.selectionPage[this.dataForJava.page - 1][0]
        && (this.selectionPage[this.dataForJava.page - 1][0].check = false)
      // 全选之后如果操作了单独选中,当前状态就不是全选
      this.indeterminate = false
      if (this.selectAllFlag) {
        this.allFlagAfter = true
        this.enoughLen()
      } else {
        let num = Math.ceil(this.totalCount / this.dataForJava.pageSize)
        if (this.selectionPage.length === num) {
          this.enoughLen()
        }
      }
      this.$set(this.tableData, selectionIndex, selection)
    },
      // 筛选数据 -- 重选 取消选中
    fliterData (selection) {
      let flag = false
      console.log(this.currentSelection, 'this.currentSelection')
      this.currentSelection.filter((item, itemIndex) => {
        if (item.id === selection.id) {
          this.currentSelection.splice(itemIndex, 1)
          selection.checked = false
          flag = true
        }
      })
      if (!flag) {
        selection.checked = true
        this.currentSelection.push(selection)
      }
      return selection
    },
        // 自动全选 -- 当前页面
    autoAll () {
      // this.tableData.forEach((item, index) => {
      //   this.$refs.tableDataRef.toggleRowSelection(this.tableData[index], true)
      // })
      this.tableData.forEach((item, index) => {
        // 除去已结算的
        if (item.status === '0') {
          item.checked = true
        }
        this.currentSelection[index] = item
        this.$set(this.tableData, index, item)
      })
    },
     // 渲染页面是有选择的
    handSelected () {
      if (this.selectionPage[this.dataForJava.page - 1] && this.selectionPage[this.dataForJava.page - 1].length) {
        // 根据现有数据整合列表
        this.selectionPage[this.dataForJava.page - 1].forEach((itemPage, itemIndex) => {
          this.tableData.forEach((itemTableData, indexTable) => {
            if (itemPage.id === itemTableData.id) {
              itemPage.checked = true
              this.currentSelection[indexTable] = itemTableData
              this.$set(this.tableData, indexTable, itemPage)
            }
          })
        })
      }
    },
      // 根据不同的情况 渲染多选框
    resSelected () {
      if (this.selectAllFlag) {
        // 只针对当前页面
        if (this.selectionPage[this.dataForJava.page - 1]
          && this.selectionPage[this.dataForJava.page - 1][0]
          && !this.selectionPage[this.dataForJava.page - 1][0].check) {
          this.handSelected()
        } else {
          this.autoAll()
        }
      } else {
        this.handSelected()
      }
    },
    getTable(){
        this.resSelected()
    },
    // 头部多选框
    renderHeader (h, { column, index }) {
      return h(
        'el-checkbox', {
          'class': {
            'checkedAll': true
          },
          'props': {
            indeterminate: this.indeterminate,
            value: this.selectAllFlag
          },
          on: {
            change: this.selectAllClick
          }
        }, ['']
      )
    },
    // 全选点击
    selectAllClick () {
      this.indeterminate = false
      // 干净的点击全选
      if (!this.selectAllFlag && this.allFlagAfter) {
        this.selectAllFlag = true
        // 所有的自定义全部数据加上标志,表示现在是全选
        let num = Math.ceil(this.totalCount / this.dataForJava.pageSize)
        for (let index = 0; index < num; index++) {
          if (this.selectionPage[index]) {
            this.selectionPage[index][0] && (this.selectionPage[index][0].check = true)
          }
        }
      } else { // 先点击全选再单独点击
        if (!this.allFlagAfter) {
          this.selectAllFlag = true
          this.allFlagAfter = true
          // 再点击全选 需要当前状态清空
          this.selectionPage.forEach((itemFirst, firstIndex) => {
            if (itemFirst) {
              itemFirst[0] && (itemFirst[0].check = true)
            }
            this.selectionPage = []
          })
        } else { // 点击取消
          this.selectAllFlag = false
          this.selectionPage = []
          this.currentSelection = []
        }
      }
      // 判断后赋值
      this.tableData.forEach((item, index) => {
        if (this.selectAllFlag) {
          if (item.status === '0') {
            item.checked = true
          }
          this.currentSelection[index] = item
        } else {
          item.checked = false
        }
        this.$set(this.tableData, index, item)
      })
    },
复制代码

你可能感兴趣的:(基于vue Element-ui的el-table多选框)