结合树形结构展示信息

一、实现效果

左边是一个树形结构,展示门店的层次,并且可以进行滚动,右边是具体门店员工信息的展示

二、实现思路

1.静态结构

整体布局

采用 el-row 和 el-col 组件来构建页面布局,这是基于 Element Plus 提供的栅格系统。el-row 作为行容器,el-col 用于划分列,这里将页面分为左(占 span="4" )、右(占 span="20" )两部分,实现左右分栏效果。

左侧门店列表部分
  1. 滚动容器:使用 el-scrollbar 组件并设置高度为 80vh ,目的是当内部内容(门店列表)超出该高度时出现滚动条,方便展示更多的信息。
  2. 表格展示
    • el-table 用于呈现门店数据,是展示的核心组件。
    • v-loading="isLoading" 实现表格加载状态的显示与隐藏,当数据加载时显示加载动画,加载完成后隐藏,增强用户体验。
    • :cell-style="cellStyle" 用于设置表格单元格的样式,通过定义 cellStyle 对象来指定如字体加粗、鼠标指针样式等样式属性,提升视觉效果和交互感。
    • :data="shops" 将静态的门店数据数组 shops 绑定到表格,使表格能展示门店信息。
    • :tree-props="tableTreeProps" 配合树形数据结构,指定数据中表示子节点的字段(这里是 childs ),让表格以树形结构展示门店层级关系。
    • border 属性为表格添加边框,使表格结构更清晰。
    • default-expand-all 让表格默认展开所有层级的树形结构,方便用户一开始就能看到所有门店层级。
    • highlight-current-row 高亮当前选中的行,便于用户明确当前选择的门店。
    • row-key="selfid" 为表格的每一行指定唯一标识,方便 Vue 进行虚拟 DOM 渲染和管理。
    • size="large" 设置表格尺寸为较大规格,使内容展示更清晰。
    • @current-change="handleCurrentChange" 监听表格当前行变化事件,当用户点击不同门店行时,触发该事件并执行 handleCurrentChange 方法,用于更新右侧展示的人员信息等操作。
    • el-table-column 定义表格列,这里定义了展示 “门店” 名称的列,通过 prop="shop_name" 绑定到数据中的对应字段。
右侧门店人员信息部分
  1. 条件渲染:使用 v-if="currentShopId!== undefined" 进行条件判断,当有门店被选中(即 currentShopId 有值 )时,展示右侧区域内容,否则显示 el-empty 组件提示用户 “请选择门店” 。
  2. 添加人员按钮:当用户角色为 HR(通过 v-if="isHr" 判断 )时,展示 “添加人员” 按钮,@click="handleAddClick" 绑定点击事件,点击后执行 handleAddClick 方法,一般用于打开添加人员的对话框或页面等操作。
  3. 人员表格展示
    • 同样使用 el-table 展示门店人员信息。v-loading="isLoading" 处理表格加载状态。:data="currentShopUsers" 将当前选中门店对应的人员数据数组 currentShopUsers 绑定到表格。
    • 定义了 “用户名”(prop="username" )、“手机”(prop="mobile" )列展示人员基本信息。
    • 当用户角色为 HR 时,展示 “操作” 列,其中通过 el-popconfirm 组件实现删除确认功能,点击 “删除” 按钮弹出确认框,确认后执行 handleDeleteConfirm 方法来处理删除逻辑。

2.代码功能部分

为了方便起见,这里使用静态数据来展示

function handleCurrentChange({ selfid }) {
  currentShopId.value = selfid;
  currentShopUsers.value = staffData[selfid] || [];
}

 handleCurrentChange 函数:当左侧门店表格中当前行发生变化时(即用户点击不同门店行 ),该函数被调用。它接收包含门店 selfid 的参数,将 currentShopId 更新为当前点击门的 selfid,然后根据这个 selfid 从 staffData 中获取对应的工作人员数组,赋值给 currentShopUsers,从而实现右侧展示区域根据选中门店更新工作人员信息的功能。

三、完整代码

<template>
  <el-row>
    <el-col :span="4">
      <el-scrollbar height="80vh">
        <el-table
          v-loading="isLoading"
          :cell-style="cellStyle"
          :data="shops"
          :tree-props="tableTreeProps"
          border
          default-expand-all
          highlight-current-row
          row-key="selfid"
          size="large"
          @current-change="handleCurrentChange"
        >
          <el-table-column label="门店" prop="shop_name" />
        </el-table>
      </el-scrollbar>
    </el-col>
    <el-col :span="20">
      <div v-if="currentShopId!== undefined">
        <div class="button">
          <el-button v-if="isHr" type="primary" @click="handleAddClick">添加人员</el-button>
        </div>
        <div class="table">
          <el-table v-loading="isLoading" :data="currentShopUsers" border>
            <el-table-column label="用户名" prop="username" />
            <el-table-column label="手机" prop="mobile" />
            <el-table-column v-if="isHr" label="操作" width="140">
              <template #default="{ row }">
                <el-popconfirm
                  title="是否确定删除?"
                  @confirm="handleDeleteConfirm(currentShopId, row.userid)"
                >
                  <template #reference>
                    <el-button link type="danger">删除</el-button>
                  </template>
                </el-popconfirm>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
      <el-empty v-else description="请选择门店" />
    </el-col>
  </el-row>
</template>

<script setup>
import { ref } from 'vue';
import { ElMessage } from 'element-plus';

// 静态门店数据
const shops = ref([
  {
    level: 1,
    shop_name: '示例总店',
    childs: [
      {
        level: 2,
        shop_name: '示例分店1',
        selfid: 1,
        childs: [
          {
            level: 3,
            shop_name: '示例子分店1',
            selfid: 3
          },
          {
            level: 3,
            shop_name: '示例子分店2',
            selfid: 4
          },
          {
            level: 3,
            shop_name: '示例子分店3',
            selfid: 5
          },
          {
            level: 3,
            shop_name: '示例子分店4',
            selfid: 6
          },
          {
            level: 3,
            shop_name: '示例子分店5',
            selfid: 7
          }
        ]
      },
      {
        level: 2,
        shop_name: '示例分店2',
        selfid: 2,
        childs: [
          {
            level: 3,
            shop_name: '示例子分店6',
            selfid: 8
          },
          {
            level: 3,
            shop_name: '示例子分店7',
            selfid: 9
          },
          {
            level: 3,
            shop_name: '示例子分店8',
            selfid: 10
          }
        ]
      },
      {
        level: 2,
        shop_name: '示例分店3',
        selfid: 11,
        childs: [
          {
            level: 3,
            shop_name: '示例子分店9',
            selfid: 12
          },
          {
            level: 3,
            shop_name: '示例子分店10',
            selfid: 13
          }
        ]
      },
      {
        level: 2,
        shop_name: '示例分店4',
        selfid: 14
      },
      {
        level: 2,
        shop_name: '示例分店5',
        selfid: 15
      }
    ],
    selfid: 0
  }
]);

// 静态工作人员数据
const staffData = {
  0: [
    { username: '总店员工1', mobile: '13800000001', userid: '1' },
    { username: '总店员工2', mobile: '13800000002', userid: '2' },
    { username: '总店员工3', mobile: '13800000003', userid: '3' }
  ],
  1: [
    { username: '分店1员工1', mobile: '13800000004', userid: '4' },
    { username: '分店1员工2', mobile: '13800000005', userid: '5' },
    { username: '分店1员工3', mobile: '13800000006', userid: '6' },
    { username: '分店1员工4', mobile: '13800000007', userid: '7' },
    { username: '分店1员工5', mobile: '13800000008', userid: '8' }
  ],
  2: [
    { username: '分店2员工1', mobile: '13800000009', userid: '9' },
    { username: '分店2员工2', mobile: '13800000010', userid: '10' },
    { username: '分店2员工3', mobile: '13800000011', userid: '11' },
    { username: '分店2员工4', mobile: '13800000012', userid: '12' }
  ],
  3: [
    { username: '子分店1员工1', mobile: '13800000013', userid: '13' },
    { username: '子分店1员工2', mobile: '13800000014', userid: '14' },
    { username: '子分店1员工3', mobile: '13800000015', userid: '15' }
  ],
  4: [
    { username: '子分店2员工1', mobile: '13800000016', userid: '16' },
    { username: '子分店2员工2', mobile: '13800000017', userid: '17' }
  ],
  5: [
    { username: '子分店3员工1', mobile: '13800000018', userid: '18' },
    { username: '子分店3员工2', mobile: '13800000019', userid: '19' }
  ],
  6: [
    { username: '子分店4员工1', mobile: '13800000020', userid: '20' },
    { username: '子分店4员工2', mobile: '13800000021', userid: '21' }
  ],
  7: [
    { username: '子分店5员工1', mobile: '13800000022', userid: '22' },
    { username: '子分店5员工2', mobile: '13800000023', userid: '23' }
  ],
  8: [
    { username: '子分店6员工1', mobile: '13800000024', userid: '24' },
    { username: '子分店6员工2', mobile: '13800000025', userid: '25' }
  ],
  9: [
    { username: '子分店7员工1', mobile: '13800000026', userid: '26' },
    { username: '子分店7员工2', mobile: '13800000027', userid: '27' }
  ],
  10: [
    { username: '子分店8员工1', mobile: '13800000028', userid: '28' },
    { username: '子分店8员工2', mobile: '13800000029', userid: '29' }
  ],
  11: [
    { username: '子分店9员工1', mobile: '13800000030', userid: '30' },
    { username: '子分店9员工2', mobile: '13800000031', userid: '31' }
  ],
  12: [
    { username: '子分店10员工1', mobile: '13800000032', userid: '32' },
    { username: '子分店10员工2', mobile: '13800000033', userid: '33' }
  ],
  14: [
    { username: '分店4员工1', mobile: '13800000034', userid: '34' },
    { username: '分店4员工2', mobile: '13800000035', userid: '35' }
  ],
  15: [
    { username: '分店5员工1', mobile: '13800000036', userid: '36' },
    { username: '分店5员工2', mobile: '13800000037', userid: '37' }
  ]
};

const isLoading = ref(false);
const tableTreeProps = {
  children: 'childs'
};
const cellStyle = {
  fontWeight: 'bold',
  cursor: 'pointer'
};
const isHr = ref(true);
const currentShopId = ref();
const currentShopUsers = ref([]);

function handleCurrentChange({ selfid }) {
  currentShopId.value = selfid;
  currentShopUsers.value = staffData[selfid] || [];
}

function handleAddClick() {
  // 这里可以添加添加人员的逻辑
  ElMessage.info('添加人员功能待实现');
}

async function handleDeleteConfirm(shopId, shopUserId) {
  try {
    // 这里可以添加删除人员的逻辑
    const index = currentShopUsers.value.findIndex(item => item.userid === shopUserId);
    if (index!== -1) {
      currentShopUsers.value.splice(index, 1);
      ElMessage.success('删除成功');
    }
  } catch (error) {
    ElMessage.error('删除失败');
    console.log(error);
  }
}
</script>

<style scoped>
.button,
.table {
  margin-left: 20px;
}

.button {
  margin-bottom: 10px;
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值