Table列表复现框实现【勾选-搜索-再勾选】
- 概要
- 整体架构流程
- 代码实现
- 技术细节
- 注意
- 参考文献
概要
最近在开发时遇到一个问题,在进行表单渲染时,正常选中没有问题,单如果需要搜索选中时,一个是已选中的不会回填,二是在搜索的结果中进行选中,没有实现,经过排查,查找资料后实现。
例如:
整体架构流程
具体的实现效果
如下:
代码实现
<template>
<el-dialog
:title="departmentUsersDialogTitle"
:visible.sync="departmentUsersDialogVisible"
width="55%"
@close="handleDepartmentUserDialog">
<div class="dialog-content">
<el-container>
<el-main class="user-group-content">
<div class="user-group-panel">
<div class="user-group-search">
<el-input
v-model="searchUserValue"
size="small"
placeholder="请选择用户名称"
@input="handleSearch"
/>
</div>
<div class="user-group-table">
<el-table ref="userTableDataRef" size="small" :data="filteredData" style="width: 100%;height: 100%"
@selection-change="handleSelectionChange"
:row-key="getRowKey">
<el-table-column type="selection" width="55" :reserve-selection="true"/>
<el-table-column property="userName" label="姓名" width="120">
<template #default="scope">{{scope.row.userName}}</template>
</el-table-column>
<el-table-column property="userCode" label="人员编码" width="120" />
<el-table-column property="departmentName" label="所属部门" />
</el-table>
</div>
</div>
</el-main>
<el-aside class="user-select-content">
<div class="user-select-panel">
<div class="user-select-title">
<label>已选区</label>
</div>
<div>
<el-tag size="small" v-for="(userItem,userIndex) in departmentUsers" :key="userIndex" @close="handleCloseUserTag(userItem)" closable type="primary" style="margin: 5px">
{{ userItem.userName}}
</el-tag>
</div>
</div>
</el-aside>
</el-container>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="handleDepartmentUserDialog" size="small">取 消</el-button>
<el-button type="primary" @click="confirmDepartmentUserDialog" size="small">确 定</el-button>
</span>
</el-dialog>
</template>
<script>
import {getDepartmentUserApi} from "@/api";
export default {
name: "departmentUserDialog",
props:{
departmentUsersTitle:{
type:String,
required:true
},
departmentUserVisible:{
type:Boolean,
required:true
},
selectedDepartmentData:{
type:Object,
required:true
},
allDepartmentModel:{
type:Array,
required:true
},
},
mounted() {
const _that = this;
_that.departmentUsersDialogTitle=_that.departmentUsersTitle;
_that.departmentUsersDialogVisible=_that.departmentUserVisible;
//选择的部门
_that.selectedDepartment = _that.selectedDepartmentData;
_that.departmentUsers=_that.selectedDepartmentData.users || [];
_that.departmentThee = _that.allDepartmentModel;
//初始化树节点
_that.initializeUserData();
},
data(){
return{
departmentUsersDialogTitle:'',
departmentUsersDialogVisible:false,
searchDepartment:'',
departmentThee:[],
defaultProps: {
children: 'children',
label: 'label'
},
searchUserValue:'',
userTableData:[],
departmentUsers:[],
selectedDepartment:{},
// 初始时默认选中的节点
defaultCheckedKeys: [],
filteredData: [], // 过滤后的数据,用于显示
//防止回显成功前对表格进行操作的标识,防止在调用toggleRowSelection方法改变选中状态,会调用@selection-change="handleSelectionChange"
stopReBack: false,
}
},
methods:{
getRowKey(row) {
return row.userId;
},
/**
* 输入搜索
*
*/
handleSearch() {
const _that = this;
//过滤数据
_that.filterUserData().then(() => {
//初始化所选表单
_that.setDefaultSelections();
});
},
/**
* 过滤用户数据
*/
filterUserData() {
const _that = this;
const searchUserValue = (_that.searchUserValue || '').toLowerCase();
//过滤后的数据
const searchTableData = _that.userTableData.filter(tableDta => {
return (tableDta['userName'].toLowerCase()).includes(searchUserValue);
}) || [];
_that.filteredData = searchTableData;
},
/**
* 初始化表单选中项
*/
setDefaultSelections() {
// 遍历defaultSelectedIds,并找到对应的行来选中
const _that=this;
_that.stopReBack = true;
_that.departmentUsers.forEach(user => {
const row = _that.filteredData.find(row => row.userId === user.userId);
if (row) {
_that.$refs['userTableDataRef'].toggleRowSelection(row,true);
}
});
_that.stopReBack = false;
},
/**
* 初始化用户数据
*
*/
initializeUserData(){
const _that = this;
//初始化所选部门的用户
_that.findDeptUser().then(() =>{
_that.filteredData = _that.userTableData;
//初始化所选表单
_that.setDefaultSelections();
})
},
/**
* 部门树节点过滤
*
* @param value
* @param data
* @returns {boolean}
*/
departmentFilterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
/**
* 删除用户的Tag
* @param userItem
*/
handleCloseUserTag(userItem){
const _that = this;
_that.departmentUsers.splice(_that.departmentUsers.indexOf(userItem), 1);
_that.$refs['userTableDataRef'].toggleRowSelection(userItem,false);
},
/**
* 确定弹框,
*/
confirmDepartmentUserDialog(){
const _that = this;
const selectData = _that.selectedDepartment;
_that.$emit('actionDepartmentUsers', {
distributeId:selectData.distributeId,
distributeName:selectData.distributeName,
users: _that.departmentUsers
});
},
/**
* 取消弹框,
*/
handleDepartmentUserDialog(){
const _that = this;
_that.$emit('closeDepartmentUsersDialog');
},
/**
* 根据部门ID获取用户数据
*
* @returns {Promise<void>}
*/
async findDeptUser() {
const _that = this;
const departmentJSON = _that.selectedDepartment || {};
await getDepartmentUserApi({
departmentId: departmentJSON['distributeId'] || '',
}).then(res => {
_that.userTableData = res.data || [];
}).catch(err => {
console.error('获取部门用户数据异常', err);
})
},
handleSelectionChange(val){
const _that = this;
if (_that.stopReBack) {
return false;
}
_that.departmentUsers = val;
},
}
}
</script>
<style scoped lang="scss">
div.dialog-content{
.el-container{
width: 100%;
height: 500px;
.el-aside{
width: 25% !important;
border: 1px #dcdfe6 solid;
padding: 10px;
div.user-department-panel{
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
background-color: #ffffff;
}
div.user-department-tree{
flex: 1;
padding: 5px 0;
}
div.user-select-panel{
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
background-color: #ffffff;
div.user-select-title{
height: 32px;
line-height: 32px;
text-align: center;
border-bottom: 1px #dcdfe6 solid;
}
}
}
.el-main{
border: 1px #dcdfe6 solid;
margin:0 10px;
padding: 10px;
div.user-group-panel{
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
background-color: #ffffff;
div.user-group-table{
flex: 1;
padding: 5px 0;
}
}
}
}
}
</style>
技术细节
其中主要需要查看的参数、组件、方法如下:
- 组件(主要用法去element-ui官网查看)
:row-key=“getRowKey”:行数据的 Key,用来优化 Table 的渲染;在使用 reserve-selection 功能与显示树形数据时,该属性是必填的。类型为 String 时,支持多层访问:user.info.id,但不支持 user.info[0].id,此种情况请使用 Function。
:reserve-selection=“true”:仅对 type=selection 的列有效,类型为 Boolean,为 true 则会在数据更新之后保留之前选中的数据(需指定 row-key)
@selection-change=“handleSelectionChange”:当选择项发生变化时会触发该事件 - 参数
//防止回显成功前对表格进行操作的标识,防止在调用toggleRowSelection方法改变选中状态,会调用@selection-change=“handleSelectionChange”
stopReBack: false, - 方法:
//初始化树节点
_that.initializeUserData();
注意
在使用toggleRowSelection()方法时要确保数据已经渲染出来,所以我使用了.then函数。
参考文献
table列表复现框【勾选-搜索-再勾选】功能
el-table中实现数据回显自动勾选
el-table复选框全部勾选以及勾选回显