文章记录大概业务解决过程
- el-table的多选只能选择当前页,不能记录选中状态
- 业务需求需要点击全选记录所有页的选中状态,记录当前的选择项
- 1.直接在el-table type="selection"功能上修改
- 优点:利用el-table的多选功能实现 this.$refs.multipleTable.toggleAllSelection()
- 缺点:实现中覆盖el-table多选功能,导致重复依赖
template:
<el-table ref="multipleTable" :data="tableData"
@selection-change="changeFun"
@select="selectMemoryFn"
@select-all="selectAll">
<el-table-column
width="55"
label="213"
type="selection"
class-name='selection-self' // 为了操作dom
>
</el-table-column>
</el-table>
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">
<!-- type="selection" -->
<template slot-scope="scope">
<!-- 已结算则不可选择 -->
<el-checkbox @change="selectChange(scope.row, scope.$index)" v-model="scope.row.checked" :disabled="scope.row.status === '1'"></el-checkbox>
</template>
</el-table-column>
// 点击到了和表格一样多
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)
})
},