vue3使用el-tree-select树形动态加载数据

本文详述了前端项目、文件、目录的命名规范,包括全小写、驼峰式、下划线分隔等规则。同时,讨论了CSS命名的细节,如位置、大小、文字、背景及其他属性的简写和前缀使用。JavaScript的命名规范涵盖变量、常量、方法和类的命名约定,以及图片命名和CSS样式的组织结构。此外,还介绍了JS函数命名的动词列表及常见文件命名惯例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TreeSelect 树形选择
含有 下拉菜单的树形选择器,结合了 e1-tree 和 e1-select 两个组件的功能

el-tree-select

请添加图片描述

<template>
  <div class="main">
    <div class="header">
      <el-form :model="form" label-width="auto">
        <!-- 区域选择  -->
        <el-form-item label="区域" style="width: 200px; float: left">
           <el-tree-select
              v-model="form.areaIdList"
              :data="optionOrgs"
              :props="defaultProps"
              clearable
              multiple
              show-checkbox
              check-strictly
              node-key="id"
              placeholder="请选择区域"
              style="width: 220px"
              @change="handleAreaChange(form.areaIdList)"
              collapse-tags
            />
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script lang="ts">
import { ref, reactive, toRefs, onMounted } from "vue";
import { useRouter, useRoute } from "vue-router";
export default {
  name: "",
  setup() {
    let router = useRouter(),
      route = useRoute();
 
    const data: any = reactive({
      form: {
        areaIdList: [], // 选中的区域ID列表
      },
      optionOrgs: [], // 区域选项 
    });
 
    // 树形选择属性配置
    const defaultProps = {
      label: "name",
      children: "children",
      isLeaf: (data: any) => {
        return !data.children || data.children.length === 0;
      },
    };
 
    const loading = ref(false);
    // 递归处理区域数据,添加children字段
    const processAreaData = (areas: any) => {
      return areas.map((area: { id: any; name: any; parentId: any; areaVos: any; }) => ({
        id: area.id,
        name: area.name,
        parentId: area.parentId,
        children: area.areaVos ? processAreaData(area.areaVos) : []
      }));
    };
    // 节点数据
    const getAllAreas = async () => {
      try {//父子节点统一结果返回
        const  res={
        "code": 1,
        "message": null,
        "success": true,
        "data": [
        {
            "id": 358,
            "areaCode": "1865",
            "name": "常州市",
            "areaGrade": 1,
            "parentId": 0,
            "areaMap": "",
            "areaPos": "",
            "isvalid": null,
            "areaVos": [
                {
                    "id": 361,
                    "areaCode": "7863",
                    "name": "万达广场中心店",
                    "areaGrade": 0,
                    "parentId": 358,
                    "areaMap": "",
                    "areaPos": "",
                    "isvalid": null,
                    "areaVos": []
                },
                {
                    "id": 362,
                    "areaCode": "7862",
                    "name": "东城营业厅",
                    "areaGrade": 0,
                    "parentId": 358,
                    "areaMap": "",
                    "areaPos": "",
                    "isvalid": null,
                    "areaVos": []
                }
            ]
        }
    ]
}
        data.optionOrgs = processAreaData(res.data);
        console.log(data.optionOrgs,'opop');
        
      } catch (error) {
        console.error("获取区域数据失败:", error);
      }
    };
 const handleAreaChange = async (selectedAreaIds: number[]) => {
    console.log(selectedAreaIds,'selectedAreaIds');
  }


    onMounted(async () => {
      try {
        await getAllAreas();
        await handleAreaChange([]);
      } catch (error) {
        console.error("初始化失败:", error);
      }
    });
 
    const refData = toRefs(data);
    return {
      ...refData,
      defaultProps,
      handleAreaChange,
      loading,
    };
  },
};
</script>

动态显示子节点

在这里插入图片描述

勾选父节点懒加载对应展示子节点
初始化展示父节点 点击父节点的id作为子节点的入参加载子节点的数据
 <el-tree-select
            v-model="form.areaIdList"
            :data="optionOrgs"
            :props="defaultProps"
            :load="loadNode"
            lazy
            clearable
            multiple
            check-strictly
            node-key="id"
            placeholder="请选择区域"
            style="width: 220px"
            @change="handleAreaChange(form.areaIdList)"
            collapse-tags
          />
<script lang="ts">
import { ref, reactive, toRefs, onMounted } from "vue";
export default {
setup() {
const data: any = reactive({
 form: {
        areaIdList: [], // 勾选的区域ID列表
      },
      optionOrgs: [], // 区域选项(树形结构 由懒加载填充)
})
      // 树形选择属性配置
    const defaultProps = {
      label: "name",
      children: "children",
      isLeaf: (data: any) => {
        return data.child === 0;
      },
    };
    // 懒加载树节点数据
    const loadNode = async (node: any, resolve: Function) => {
      console.log(node,'opop');
      
      try {
        let res;

        if (node.level === 0) {
          res = await getOrg({ pid: 0 });//父节点数据
        } else {
          res = await getOrgSon({ areaId: node.data.id });//点击父节点懒加载子节点数据
        }

        const formattedNodes = res.map((item) => ({
          id: item.id,
          name: item.name,
          parentId: item.parentId,
          child: item.child,
        }));

        resolve(formattedNodes);
      } catch (error) {
        console.error("加载节点失败:", error);
        resolve([]);
      }
    };

const refData = toRefs(data);
    return {
      ...refData,
      loadNode,
}
}
}
</script>

动态显示勾选数据

2个选择器一个是TreeSelect(el-tree-select)
另一个是el-select
el-select的数据是基于el-tree-select的勾选动态加载显示的
勾选多个时以逗号分隔  在区域选择对应值 
设备随着区域选择的值当成入参请求接口返回动态展示数据
区域的值与设备展示数据是同步的
    <!-- 区域选择  -->
        <el-form-item label="区域">
           <el-tree-select
              v-model="form.areaIdList"
              :data="optionOrgs"
              :props="defaultProps"
              clearable
              multiple
              show-checkbox
              check-strictly
              node-key="id"
              placeholder="请选择区域"
              style="width: 220px"
              @change="handleAreaChange(form.areaIdList)"
              collapse-tags
            />
        </el-form-item>
        
        <!-- 设备选择 -->
        <el-form-item label="设备">
           <el-select
              v-model="form.deviceIdList"
              multiple
              clearable
              filterable
              placeholder="请选择设备"
              style="width: 220px"
              collapse-tags
              :loading="loading"
            >
              <el-option
                v-for="item in deviceOptions"
                :key="item.id"
                :label="item.name"
                :value="item.id"
              />
            </el-select>
        </el-form-item>
      <el-button
          type="primary"
          @click="btnInquire"
          plain
          small
          style="margin: 0 0 0 10px"
          >查询</el-button
        >
<script lang="ts">
import { ref, reactive, toRefs, onMounted } from "vue";
export default {
setup() {
const data: any = reactive({
 form: {
        areaIdList: [], // 选中的区域ID列表
        deviceIdList: [], // 选中的设备ID列表
      },
      optionOrgs: [], // 区域选项 
      deviceOptions: [], // 设备选项
      allDevices: [], // 存储所有设备数据
})
  // 树形选择属性配置
    const defaultProps = {
      label: "name",
      children: "children",
      isLeaf: (data: any) => {
        return !data.children || data.children.length === 0;
      },
    };
 
    const loading = ref(false);

    // 递归处理区域数据,添加children字段
    const processAreaData = (areas: any[]) => {
      return areas.map(area => ({
        id: area.id,
        name: area.name,
        parentId: area.parentId,
        children: area.areaVos ? processAreaData(area.areaVos) : []
      }));
    };

    // 区域节点数据
    const getAllAreas = async () => {
       //getOrg区域接口
        const res = await getOrg({ pid: 0 });
        data.optionOrgs = processAreaData(res);
        console.log("区域数据加载成功:", data.optionOrgs.length);
    };
 
 
// 处理区域变化 - 根据选中的区域动态加载设备 支持多选
// const handleAreaChange = async (selectedAreaIds: number[]) => {
//   console.log("区域选择变化:", selectedAreaIds);

//   // 重置设备选择
//   data.form.deviceIdList = [];

//   try {
//     loading.value = true;

//     let params = {};
//     if (selectedAreaIds.length > 0) {
//       // 修复:将 areaId 转为逗号分隔的字符串
//       params = { areaId: selectedAreaIds.join(',') };
//     } else {
//       // 默认加载 areaId = 0 的设备
//       params = { areaId: '0' };
//     }

//     const res = await getOrgSon(params); // ✅ 调用设备接口

//     data.deviceOptions = res.map(device => ({
//       id: device.id,
//       name: device.name
//     }));

//     console.log("加载设备数量:", data.deviceOptions.length);
//   } catch (error) {
//     console.error("获取设备失败:", error);
//     ElMessage.error("获取设备数据失败");
//     data.deviceOptions = [];
//   } finally {
//     loading.value = false;
//   }
// };
// 只支持单选 累加计
 const handleAreaChange = async (selectedAreaIds: number[]) => {
  data.form.deviceIdList = [];
  data.deviceOptions = [];

  if (selectedAreaIds.length === 0) {
    // getOrgSon设备接口
    const res = await getOrgSon({ areaId: 0 });
    data.deviceOptions = res.map(device => ({
      id: device.id,
      name: device.name
    }));
    return;
  }

  // 依次请求每个区域下的设备
  const allDevices = [];
  for (const areaId of selectedAreaIds) {
    try {
      const res = await getOrgSon({ areaId });
      allDevices.push(...res);
    } catch (error) {
      console.error(`获取区域 ${areaId} 的设备失败`, error);
    }
  }

  // 去重
  const uniqueDevices = [...new Map(allDevices.map(item => [item.id, item])).values()];
  data.deviceOptions = uniqueDevices.map(device => ({
    id: device.id,
    name: device.name
  }));
};

  const tableLIst = async () => {
   //查询的入参表格数据
      const params = {
        keyword: data.form.name,
        limit: data.tableList.limit,
        offset: (data.tableList.offset - 1) * data.tableList.limit,
        order: data.tableList.order,
        sort: data.tableList.sort,
        endTime: data.tableList.endTime,
        startTime: data.tableList.startTime,
      };
 
      // 处理设备筛选条件
  if (data.form.deviceIdList.length > 0) {
    // 如果选择了设备,传递选中的设备ID列表
    params['deviceIdList'] = data.form.deviceIdList.join(',');
  } else {
    // 如果没有选择设备,默认传递所有设备的ID列表
    if (data.deviceOptions.length > 0) {
      const allDeviceIds = data.deviceOptions.map(device => device.id);
      params['deviceIdList'] = allDeviceIds.join(',');
    }
  }
  
      try {
        const data1 = await Offlinelist(params);
        data.tableData = data1;
      } catch (error) {
        console.error("获取表格数据失败:", error);
      }
    };
      onMounted(async () => {
        await getAllAreas();//初始化区域数据
        await handleAreaChange([]);//勾选设备值
        await tableLIst();//查询表格数据
    });
const refData = toRefs(data);
    return {
      ...refData,
       defaultProps,
      tableLIst,
      handleAreaChange,
      loading,
}
}
}
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值