Ruoyi-Vue-Pro芋道Vue3实现用户选择组件

前言

在企业级应用开发中,用户选择是一个非常常见的需求。无论是发送消息、分配任务,还是设置权限,我们都需要一个功能完善、体验良好的用户选择组件。本文将带你一步步实现一个基于若依 Ruoyi-Vue-Pro Vue3 的用户选择组件。

实现效果

在这里插入图片描述

思路

1. 需求分析

首先,我们需要明确组件的核心需求:

  • 支持单选和多选模式
  • 展示组织架构树
  • 实现用户搜索
  • 管理已选用户
  • 支持数据回显
  • 提供灵活的配置项

2. 设计思路

我们将组件分为三个主要部分:

1.组织架构树

  • 树形展示部门结构
  • 支持部门搜索
  • 点击部门筛选用户

2.用户列表

  • 展示用户信息
  • 支持用户搜索
  • 触底分页加载更多
  • 实现单选/多选功能

3.已选用户区

  • 显示已选用户
  • 支持单个/批量取消选择
  • 展示选择数量

实现

1. 创建子组件 components/PeopleSelect/index.vue

<template>
  <div>
      <el-dialog
      :title="'用户选择' + (type == 'multiple' ? '(多选)' : '(单选)')"
      v-model="dialogVisible"
      :width="width || '1050px'"
      :height="height || '650px'"
      :before-close="handleClose"
      append-to-body  
      >

      <div class="selectBox">
          <div class="search-area" v-show="showSearch">
              <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="0">
                  <el-row :gutter="16">
                      <el-col :span="8">
                          <el-form-item prop="nickname">
                              <el-input
                                  v-model="queryParams.nickname"
                                  placeholder="请输入用户姓名"
                                  clearable
                                  size="default"
                                  :prefix-icon="User"
                                  @keyup.enter="handleQuery"
                                  @clear="handleQuery"
                              />
                          </el-form-item>
                      </el-col>
                      <el-col :span="8">
                          <el-form-item prop="mobile">
                              <el-input
                                  v-model="queryParams.mobile"
                                  placeholder="请输入手机号码"
                                  clearable
                                  size="default"
                                  :prefix-icon="Phone"
                                  @keyup.enter="handleQuery"
                                  @clear="handleQuery"
                              />
                          </el-form-item>
                      </el-col>
                      <el-col :span="8">
                          <el-form-item>
                              <el-button-group>
                                  <el-button type="primary" :icon="Search" @click="handleQuery">搜索</el-button>
                                  <el-button :icon="Refresh" @click="resetQuery">重置</el-button>
                              </el-button-group>
                          </el-form-item>
                      </el-col>
                  </el-row>
              </el-form>
          </div>
          <div class="topBox">
              <div class="leftBox">
                  <div class="contentBox">
                      <div class="step-header">
                          <div class="step-number">1</div>
                          <div class="step-title">选择部门</div>
                      </div>
                      <div class="step-content">
                          <div class="search-input">
                              <el-input
                                  v-model="deptName"
                                  placeholder="请输入部门名称"
                                  clearable
                                  :prefix-icon="Search"
                              />
                          </div>
                          <div class="treeBox">
                              <el-tree
                                  ref="treeRef"
                                  :data="deptOptions"
                                  :props="defaultProps"
                                  :expand-on-click-node="false"
                                  :filter-node-method="filterNode"
                                  node-key="id"
                                  default-expand-all
                                  highlight-current
                                  @node-click="handleNodeClick"
                              />
                          </div>
                      </div>
                  </div>
              </div>

              <div class="leftBox">
                  <div class="contentBox">
                          <div class="step-header">
                              <div class="step-number">2</div>
                              <div class="step-title">选择用户</div>
                              <div class="step-actions" v-if="type == 'multiple'">
                                  <el-button type="text" size="small" @click="handleCheckedNodeAll(true)">全选</el-button>
                                  <el-button type="text" size="small" @click="handleCheckedNodeAll(false)">取消全选</el-button>
                              </div>
                          </div>
                      
                      <div class="peopleBox">
                          <div class="peopleList" @scroll="handleScroll">
                              <el-checkbox-group ref="peopleCheckBoxes" v-model="checkedUsers" @change="handleCheckedUsersChange" :max="type == 'single' ? 1 : 2147483647">
                                  <el-checkbox 
                                      v-for="item in list" 
                                      :label="item.username" 
                                      :key="item.id" 
                                      class="peopleCard"
                                  >
                                      <div class="peopleCardContent">
                                          <div class="avatarBox">
                                              <el-avatar 
                                                  :size="30"
                                                  :src="item.avatar"
                                                  :fallback="() => item.nickname?.substring(0,1) || item.username?.substring(0,1) || 'U'"
                                              />
                                          </div>
                                          <div class="peopleInfoBox">
                                              <div class="peopleName">{
   
   {
   
    item.nickname }}</div>
                                              <div class="peopleDetail">
                                                  <el-icon v-if="item.sex === 1" color="#409EFF"><Male /></el-icon>
                                                  <el-icon v-else-if="item.sex === 2" color="#F56C6C"><Female /></el-icon>
                                                  <el-icon v-else color="#909399"><User /></el-icon>
                                                  <span class="deptName">{
   
   {
   
    item.deptName }}</span>
                                              </div>
                                          </div>
                                      </div>
                                  </el-checkbox>
                              </el-checkbox-group>
                              <!-- 加载更多提示 -->
                              <div v-if="loading" class="loading-more">
                                <el-icon class="is-loading"><Loading /></el-icon>
                                <span>加载中...</span>
                              </div>
                              <div v-if="noMore" class="no-more">
                                没有更多数据了
                              </div>
                          </div>
                          <Pagination
                              :total="total"
                              v-model:page="queryParams.pageNo"
                              v-model:limit="queryParams.pageSize"
                              @pagination="getList"
                          />
                      </div>
                  </div>
              </div>
              <!-- this.checkedUsers -->
              <div class="leftBox">
                  <div class="contentBox">
                      <div class="step-header">
                          <div class="step-number">3</div>
                          <div class="step-title">
                              已选择用户
                              <span class="selected-count">({
   
   {
   
    selectedUserList.length }})</span>
                          </div>
                          <div class="step-actions">
                              <el-button 
                                v-if="type == 'multiple'" 
                                type="text" 
                                size="small" 
                                @click="clearAll"
                              >
                                清空
                              </el-button>
                          </div>
                      </div>
                      <div class="peopleBox">
                          <div class="peopleList">
                                  <div
                                      v-for="item in selectedUserList" 
                                      :key="item.id"
                                      class="peopleCard"
                                  
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值