需求说明,插件存在必选项(不可取消选中),并可以选择插件的版本
下图是此测试案例的效果图
测试过程:
①多页勾选插件和其版本
②依次点击保存、清空、反显,可测相关功能
下面附上完整代码,其中有部分注释
<template>
<div class="tableTest">
<h2>element-ui中table分页勾选和反显</h2>
<div class="navbtn">
<el-button type="primary" @click="saveHandle">保存</el-button>
<span>=></span>
<el-button type="danger" @click="clearHandle">清空</el-button>
<span>=></span>
<el-button type="success" @click="showHandle">反显</el-button>
</div>
<div class="tableBox">
<el-table
ref="multipleTable"
:data="tableData"
tooltip-effect="dark"
style="width: 100%"
:row-key="(row) => row.zj"
v-loading="multipleTableLoading"
@select="selecthandle"
@select-all="selectallhandle"
>
<el-table-column
:reserve-selection="true"
:selectable="checkSelectable"
type="selection"
width="55"
></el-table-column>
<el-table-column label="插件名" width="120">
<template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column>
<el-table-column label="插件版本">
<template slot-scope="scope">
<div>
<el-select
@change="(val) => selectChange(val, scope.row.zj)"
v-model="scope.row.val"
placeholder="无数据"
>
<el-option
v-for="item in scope.row.versions"
:key="item.v"
:label="item.v"
:value="item.v"
>
</el-option>
</el-select>
</div>
</template>
</el-table-column>
</el-table>
<el-pagination
class="pagination"
background
layout="prev, pager, next"
:total="total"
:page-size="3"
:current-page="page"
@prev-click="getData"
@current-change="getData"
@next-click="getData"
>
</el-pagination>
</div>
</div>
</template>
<script>
export default {
name: "multipleTable",
data() {
return {
tableData: [], //表单数据
multipleSelection: {}, //用户需要提交的选中项数据,为了减少循环,优化计算速度,使用{}
page: 1, //分页页码
total: 0, //总数据数
multipleTableLoading: false, //请求时候loading
currentPageSel: [], //当前页选中项集合
emitData: [], //用来反显的数据,模拟从后端获取
type: 1, //添加1 编辑2
mustList: [], //初始默认必选数据
};
},
components: {},
computed: {},
mounted() {
this.mustList = this.getInitMustSelection();
},
methods: {
getData(page) {
this.page = page;
this.multipleTableLoading = true;
this.dispenseServeData({ page, limit: 3 }).then((res) => {
//清空table勾选和currentPageSel
this.$refs.multipleTable.clearSelection();
this.currentPageSel = [];
this.total = res.total;
let odata = {}; //存储数据源
//第二次请求开始 使用this.multipleSelection为数据源
if (Object.keys(this.multipleSelection).length !== 0) {
odata = this.multipleSelection;
} else {
//编辑时候请求,判断emitData是否有值,没有值就从getInitMustSelection获取数据
let list =
this.type == 2 && this.emitData.length > 0
? this.emitData
: this.mustList;
console.log( this.type,this.emitData.length);
for (let i = 0; i < list.length; i++) {
odata[list[i].zj] = list[i];
}
}
this.tableData = res.data.map((n, i) => {
if (odata[n.zj]) {
this.$refs.multipleTable.toggleRowSelection(n, true);
this.currentPageSel.push(1);
n.val = odata[n.zj].val;
}
return {
...n,
};
});
this.multipleSelection = odata;
console.log(this.multipleSelection)
this.multipleTableLoading = false;
});
},
selecthandle(selection, row) {
//根据selection和this.currentPageSel数组长度对比,判断增加还是删除
if (selection.length > this.currentPageSel.length) {
//增加选中row
//非重复添加
if (!this.multipleSelection[row.zj]) {
this.multipleSelection[row.zj] = row;
}
} else {
//删除选中row
delete this.multipleSelection[row.zj];
}
this.currentPageSel = [...selection]; //存为之前的数据
},
selectallhandle(selection) {
//操作的数据是当期页请求的数据
for (let j = 0; j < this.tableData.length; j++) {
if (selection.length > this.currentPageSel.length) {
//增加
if (!this.multipleSelection[this.tableData[j].zj]) {
this.multipleSelection[this.tableData[j].zj] = this.tableData[j];
}
} else {
//删除
if (
this.multipleSelection[this.tableData[j].zj] &&
!this.tableData[j].isMustSel
) {
delete this.multipleSelection[this.tableData[j].zj];
}
}
}
this.currentPageSel = [...selection]; //存为之前的数据
},
checkSelectable(row) {
//false禁止选中
return !(row.isMustSel == 1);
},
saveHandle() {
this.emitData=[];
for (let key in this.multipleSelection) {
let {zj,name,val}=this.multipleSelection[key]
this.emitData.push({zj,name,val});
}
},
clearHandle() {
this.multipleSelection={};
this.type=1;
this.getData(1);
},
showHandle() {
this.multipleSelection={};
this.type=2;
this.getData(1);
},
selectChange(val,zj){
if(this.multipleSelection[zj]) this.multipleSelection[zj].val=val;
},
//模拟服务器分发数据
dispenseServeData(params, callback, err) {
let { page, limit } = params;
let odata = [
{
zj: 1,
name: "登录组件",
versions: [{ v: "1.0.3" }, { v: "1.0.2" }, { v: "1.0.1" }],
val: "1.0.3",
isMustSel: false,
},
{
zj: 2,
name: "个人中心模块",
versions: [{ v: "3.12.5" }],
val: "3.12.5",
isMustSel: false,
},
{
zj: 3,
name: "工作台",
versions: [{ v: "2.7.13" }],
val: "2.7.13",
isMustSel: true,
},
{
zj: 4,
name: "启动模块",
versions: [{ v: "4.0.3" }, { v: "3.0.2" }, { v: "2.0.1" }],
val: "4.0.3",
isMustSel: true,
},
{
zj: 5,
name: "广告页插件",
versions: [{ v: "4.6.2" }, { v: "4.6.1" }],
val: "4.6.2",
isMustSel: false,
},
{
zj: 6,
name: "微应用跳转插件",
versions: [{ v: "14.2.8" }],
val: "14.2.8",
isMustSel: false,
},
{
zj: 7,
name: "统计插件",
versions: [{ v: "7.0.3" }, { v: "6.3.2" }, { v: "5.0.1" }],
val: "7.0.3",
isMustSel: false,
},
{
zj: 8,
name: "日志插件",
versions: [{ v: "1.4.33" }],
val: "1.4.33",
isMustSel: false,
},
{
zj: 9,
name: "推送插件",
versions: [{ v: "4.0.2" }, { v: "4.0.1" }],
val: "4.0.2",
isMustSel: false,
},
{
zj: 10,
name: "活体检测模块",
versions: [{ v: "2.5.1" }, { v: "2.5.0" }],
val: "2.5.1",
isMustSel: true,
},
{
zj: 11,
name: "手写签名插件",
versions: [{ v: "1.0.5" }],
val: "1.0.5",
isMustSel: false,
},
];
return new Promise((resolve, reject) => {
setTimeout(() => {
let callbackData = {
data: [...odata].splice((page - 1) * limit, limit),
total: odata.length,
};
resolve(callbackData);
}, 500);
});
},
//分页情况下需要预先知道默认的必选项数据,模拟后端接口提供
getInitMustSelection() {
this.getData(1);
return [
{
zj: 3,
name: "工作台",
val: "2.7.13",
},
{
zj: 4,
name: "启动模块",
val: "4.0.3",
},
{
zj: 10,
name: "活体检测模块",
val: "2.5.1",
},
];
},
},
};
</script>
<style lang='less' rel='stylesheet/less' scoped>
// @import "./../../assets/less/common.less";
.tableTest {
width:1000px;
min-height: 660px;
margin: 100px auto 0;
text-align: left;
}
.navbtn {
margin-top: 20px;
}
.tableBox {
margin-top: 20px;
padding: 15px 20px;
border-radius: 10px;
border: 1px solid #dfdfdf;
box-shadow: 0 0 10px #dfdfdf;
overflow: hidden;
.pagination {
margin-top: 20px;
}
}
</style>