实现效果
在主页面引入自定义弹窗组件,点击按钮打开弹窗,选中列表数据点击确定后返回数据到主页面展示。在主页面可以对列表数据进行删除操作,删除后再打开弹窗时要实现删除的数据取消选中,未删除的保持勾选状态。
-
主页面为前面实现的列表展开收起页(点击查看)
-
点击打开弹窗
-
现在选中了三个事项
-
点击删除按钮删除一个
-
再次打开弹窗,未删除的数据回显勾选,被删除的数据已取消选中
弹窗组件代码
数据都是造的数据,未对接接口
<template>
<div>
<el-dialog :visible.sync="visible" :title="dialogTitle" width="70%" @close="$emit('close', $event)" :before-close="handleCloseSelection">
<el-divider style="margin-top: 0px"></el-divider>
<el-row>
<el-col :span="24">
<el-form :model="queryParams" ref="queryParams" :inline="true">
<el-form-item>
<el-select v-model="queryParams.dept" clearable filterable placeholder="所属部门">
<el-option v-for="(dept, index) in deptList" :label="dept" :value="dept" :key="index"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-select v-model="queryParams.businessType" clearable filterable placeholder="业务分类">
<el-option v-for="(business, index) in businessList" :label="business" :value="business" :key="index"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-select v-model="queryParams.authorize" clearable filterable placeholder="授权情况">
<el-option v-for="(authorize, index) in authorizedList" :label="authorize" :value="authorize" :key="index"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-input v-model="queryParams.itemName" clearable placeholder="请输入事项名称或编码"></el-input>
</el-form-item>
</el-form>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-table :data="itemInfoList" @selection-change="handleSelectionChange" :header-cell-style="{background:'rgb(249 250 252)', color: '#909399'}" ref="itemTable" border v-loading="loading" :row-key="getRowKey" style="margin-top: -10px">
<el-table-column align="center" type="selection" prop="selection" width="75" reserve-selection />
<el-table-column align="center" label="序号" type="index" width="75" />
<el-table-column align="center" label="事项名称" prop="itemName" />
<el-table-column align="center" label="事项编码" prop="itemCode" width="160" />
<el-table-column align="center" label="所属部门" prop="dept" />
<el-table-column align="center" label="业务分类" prop="businessType" />
<el-table-column align="center" label="授权" prop="authorize" width="100">
<template slot-scope="scope">
<span v-if="scope.row.authorize != null && scope.row.authorize > 0">
授权 <span style="color: #4f96fb">{{ scope.row.authorize }}</span> 人
</span>
<span v-if="scope.row.authorize == null || scope.row.authorize == 0" style="color: rgb(153, 153, 153)">
未授权
</span>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="4" style="padding-top: 15px;">
已选 <span style="color: #4F96FB;">{{ chooseSize }}</span> 个
</el-col>
<el-col :span="20">
<el-pagination style="float: right" :current-page="currentPage" :page-sizes="[100, 200, 300, 400]" :page-size="100" layout="total, sizes, prev, pager, next, jumper" :total="total">
</el-pagination>
</el-col>
</el-row>
<!-- 操作按钮 -->
<el-row :gutter="20" style="margin-top: 20px">
<el-col :span="12">
<el-button type="primary" @click="handleSubmitSelection" style="float: right">确定</el-button>
</el-col>
<el-col :span="12">
<el-button @click="handleCancelSelection">取消</el-button>
</el-col>
</el-row>
</el-dialog>
</div>
</template>
<script>
export default {
// 事项选择弹窗
name: "ItemInfoDialog",
components: {},
model: {
prop: "open",
event: "close",
},
data() {
return {
// 当前页码
currentPage: 1,
// 总数
total: 0,
// 当前选中数据
items: [],
// 是否打开弹窗
visible: false,
// 遮罩层
loading: false,
// 项目表格数据
itemInfoList: [],
// 查询参数
queryParams: {
dept: null,
businessType: null,
authrize: null,
itemName: null
},
// 部门信息
deptList: ["政务服务数据管理局", "智慧城市事业管理局", "智慧运营事业管理局"],
// 业务分类
businessList: ["依申请类政务服务 ", "业务类B", "业务类C"],
// 授权情况
authorizedList: ['未授权', '已授权'],
// 弹窗标题
dialogTitle: "选择事项",
// 加载遮罩层
loading: false,
// 已选条数
chooseSize: 0,
};
},
props: {
// 控制弹窗开关
open: {
type: Boolean,
default: false,
},
// 回显删除选项
rmList: {
type: Array,
default: () => []
},
},
created() {},
watch: {
open(val) {
this.visible = val;
// 初始化数据
if (this.visible) {
this.loading = true;
this.itemInfoList = [{
'id': 1,
'itemName': '医师执业证书(首次注册)',
'itemCode': '440400838',
'dept': '政务服务数据管理局',
'businessType': '依申请类政务服务',
'authorize': 6
}, {
'id': 2,
'itemName': '医师执业证书(变更)',
'itemCode': '12345678',
'dept': '政务服务数据管理局',
'businessType': '依申请类政务服务',
'authorize': 0
}, {
'id': 3,
'itemName': '咨询事项名称1',
'itemCode': '09876543',
'dept': '政务服务数据管理局',
'businessType': '依申请类政务服务',
'authorize': 6
}, {
'id': 4,
'itemName': '咨询事项名称2',
'itemCode': '440404238',
'dept': '政务服务数据管理局',
'businessType': '依申请类政务服务',
'authorize': 6
}, {
'id': 5,
'itemName': '咨询事项名称3',
'itemCode': '4423434',
'dept': '政务服务数据管理局',
'businessType': '依申请类政务服务',
'authorize': 6
}];
this.total = this.itemInfoList.length;
this.loading = false;
// 打开时回显数据
this.echoChooseItems();
}
}
},
methods: {
// 选择项改变
handleSelectionChange(selection) {
this.items = selection;
this.chooseSize = this.items.length;
},
// 提交按钮操作传已选择项到父页面
handleSubmitSelection() {
this.beforeCloseOpr();
// 除了数据同时传当前关闭弹窗的操作类型opr(提交关闭submit | 取消关闭 | 右上角'x'按钮关闭)
this.$emit("choose", [{
'items': this.items,
'opr': 'submit'
}]);
},
// 取消按钮操作传已选择项到父页面
handleCancelSelection() {
this.beforeCloseOpr();
// 除了数据同时传当前关闭弹窗的操作类型
this.$emit("choose", [{
'items': this.items,
'opr': 'cancel'
}]);
},
// 关闭弹窗按钮操作传已选择项到父页面
handleCloseSelection() {
this.beforeCloseOpr();
// 除了数据同时传当前关闭弹窗的操作类型
this.$emit("choose", [{
'items': this.items,
'opr': 'close'
}]);
},
// 回显(勾选)已选事项
echoChooseItems() {
if (this.rmList.length > 0) {
for (let i = 0; i < this.rmList.length; i++) {
this.$refs.itemTable.toggleRowSelection(this.rmList[i], false);
}
}
},
// 返回行数据key
getRowKey(row) {
return row.id;
},
// 弹窗关闭前操作
beforeCloseOpr() {
this.visible = false;
// 关闭前对同一条数据做两次选中切换操作(处理多次删除列表回显选中bug)
if (this.items.length > 0) {
let item = this.items[this.items.length - 1];
this.$refs.itemTable.toggleRowSelection(item);
this.$refs.itemTable.toggleRowSelection(item);
}
}
},
};
</script>
<style lang="less" scoped>
// 横线上下距离
/deep/ .el-divider--horizontal {
margin-top: 0px;
margin-bottom: 10px;
}
// 翻页器边距
/deep/ .el-pagination {
margin-top: 10px;
}
// 竖线长度
/deep/ .el-divider--vertical {
height: 21em;
margin-left: -27.5%;
}
// 已选用户按钮
/deep/ .el-button--medium {
padding: 0px 10px;
}
</style>
主页面代码
- 展开列表
<!-- 事项列表 -->
<div class="itemBoard" id="itemBoard">
<!--展开/收起按钮 -->
<el-button
type="text"
style="float: right; margin-right: -15px;"
id="closeItemBtn"
@click="closeItemShow"
v-show="form.chooseItems.length > 0">
{{showMoreText}}
<i :class="showAll ? 'el-icon-arrow-up ': 'el-icon-arrow-down'"></i>
</el-button>
<div v-for="(item, index) in form.chooseItems" :key="index">
{{ item.itemName }}
<el-button size="medium" type="text" icon="el-icon-circle-close" @click="handleDelItem(item)"></el-button>
</div>
</div>
- 组件引用:import引入文件后在
components
注册组件
<!-- 事项选择弹窗 -->
<ItemInfoDialog v-model="itemDialogVisit" :rmList="rmList" @choose="handleItemChoose($event)"></ItemInfoDialog>
- JS
/**
* 事项弹窗关闭事件
*/
handleItemChoose(val) {
// 获取弹窗选中列表
if (val[0].opr == 'submit') {
this.form.chooseItems = val[0].items;
}
// 防止第一次打开弹窗点关闭或取消也把所选列表获取过来
if (this.form.chooseItems.length > 0 && (val[0].opr == 'cancel' || val[0].opr == 'close')) {
this.form.chooseItems = val[0].items;
}
// 重置删除列表
this.rmList = [];
},
/**
* 删除事项选择
*/
handleDelItem(item) {
// 去除在已选事项中对应的元素
this.form.chooseItems = this.form.chooseItems.filter((choose) => {
return choose.id != item.id;
})
// 把删除的元素添加到删除集合
this.rmList.push(item);
},
/**
* 打开事项选择弹窗
*/
handleAddItem() {
this.itemDialogVisit = true;
}
要点
reserve-selection
+row-key
配合使用
- 回显时候传入删除的列表集合,循环对删除的列表使用
toggleRowSelection
取消选中