Table列表复现框实现【勾选-搜索-再勾选】

Table列表复现框实现【勾选-搜索-再勾选】

    • 概要
    • 整体架构流程
    • 代码实现
    • 技术细节
    • 注意
    • 参考文献

概要

最近在开发时遇到一个问题,在进行表单渲染时,正常选中没有问题,单如果需要搜索选中时,一个是已选中的不会回填,二是在搜索的结果中进行选中,没有实现,经过排查,查找资料后实现。

例如:

整体架构流程

具体的实现效果
如下:
Table列表复现框实现【勾选-搜索-再勾选】_第1张图片
Table列表复现框实现【勾选-搜索-再勾选】_第2张图片

代码实现

<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}
     */
    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复选框全部勾选以及勾选回显

你可能感兴趣的:(java,开发语言,elementui,vue)