应无所住,而生其心
排名
1
文章
861
粉丝
112
评论
163
net core webapi post传递参数
庸人 : 确实坑哈,我也是下班好了好几次,发现后台传递对象是可以的,但...
百度编辑器自定义模板
庸人 : 我建议换个编辑器,因为现在百度富文本已经停止维护了,用tinymec...
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术

element plus 的Tree 懒加载。省市县镇村树形懒加载

245人阅读 2025/3/12 10:45 总访问:5237554 评论:0 收藏:0 手机
分类: 前端


这里的示例代码是做的县镇村tree懒加载联动数据。接口数据这些换成自己的就行。有根据countyId查询区县下面镇的数据,有根据镇id查询镇下面村的数据等待接口。受限这些原始的表结构,县镇村是三种不同的表,这个接口根据自己的实际情况出来就行。

基础的代码如下

  1. <template>
  2. <div class="app-container">
  3. <el-card>
  4. <el-tree
  5. :data="treeData"
  6. :props="defaultProps"
  7. lazy
  8. :load="loadNode"
  9. node-key="id"
  10. @node-click="handleNodeClick"
  11. />
  12. </el-card>
  13. </div>
  14. </template>
  15. <script setup lang="ts" name="tasks">
  16. import { defineAsyncComponent, reactive, onMounted, toRefs, ref } from 'vue';
  17. import request from '/@/utils/requestTools';
  18. const state = reactive({
  19. title: '更新',
  20. schoolID: null,
  21. schoolList: [
  22. {
  23. id: 1,
  24. name: '小',
  25. },
  26. {
  27. id: 2,
  28. name: '大',
  29. },
  30. ],
  31. });
  32. // 定义树形数据的结构
  33. interface TreeNode {
  34. id: number;
  35. label: string;
  36. children?: TreeNode[];
  37. isLeaf?: boolean; // 用于标识是否为叶子节点(村数据)
  38. countyId?: string; // 区县ID,用于乡镇数据的加载
  39. townId?: string; // 乡镇ID,用于村数据的加载
  40. villageId?: string; // 村ID,用于组数据的加载
  41. }
  42. // 初始化树形数据,只包含区县节点
  43. const treeData = ref<TreeNode[]>([]);
  44. // 定义Tree组件的props
  45. const defaultProps = ref<any>({
  46. children: 'children',
  47. label: 'label',
  48. isLeaf: 'isLeaf', // 自定义属性,用于标识叶子节点
  49. });
  50. // 加载节点数据的方法
  51. const loadNode = async (node: any, resolve: any) => {
  52. if (node.level === 0) {
  53. // 根节点,加载所有区县数据
  54. try {
  55. // const response = await axios.get('/api/api1');
  56. // const data = response.data.data;
  57. const result: any = await request.get('/watertap/api/County/getAllCountyByCityId',{ choiseCity: '530600000000'});
  58. const data = result.data;
  59. const counties = data.map((county:any) => ({
  60. id: county.id,
  61. label: county.name,
  62. countyId: county.countyId,
  63. isLeaf: false, // 区县节点不是叶子节点
  64. }));
  65. resolve(counties);
  66. } catch (error) {
  67. console.error('加载区县数据失败:', error);
  68. resolve([]);
  69. }
  70. } else if (node.level === 1 && node.data.countyId) {
  71. // 区县节点,加载对应的乡镇数据
  72. try {
  73. // const response = await axios.get(`/api/api2`, {
  74. // params: { countyId: node.data.countyId },
  75. // });
  76. // const data = response.data.data;
  77. const result: any = await request.get('/watertap/api/town/getTownByCountyId', { countyId: node.data.countyId });
  78. const data = result.data;
  79. const towns = data.map((town:any) => ({
  80. id: town.id,
  81. label: town.name,
  82. townId: town.townId,
  83. isLeaf: false, // 乡镇节点不是叶子节点
  84. }));
  85. resolve(towns);
  86. } catch (error) {
  87. console.error('加载乡镇数据失败:', error);
  88. resolve([]);
  89. }
  90. } else if (node.level === 2 && node.data.townId) {
  91. // 乡镇节点,加载对应的村数据
  92. try {
  93. // const response = await axios.get('/api/api3', {
  94. // params: { townId: node.data.townId.replace('townId:', '') }, // 假设townId字段需要处理以匹配API要求
  95. // });
  96. const result: any = await request.get('/watertap/api/village/GetVillageByTownId', { townId:node.data.townId });
  97. // 注意:这里isLeaf应为true
  98. const data = result.data;
  99. const villages = data.map((village:any) => ({
  100. id: village.id, // 假设村数据中有id字段
  101. label: village.name, // 假设村数据中有name字段
  102. villageId:village.villageId,
  103. isLeaf: true, // 村节点是叶子节点
  104. }));
  105. resolve(villages);
  106. } catch (error) {
  107. console.error('加载村数据失败:', error);
  108. resolve([]);
  109. }
  110. } else {
  111. resolve([]);
  112. }
  113. };
  114. // 处理节点点击事件
  115. const handleNodeClick = (data: TreeNode) => {
  116. console.log('点击的节点:', data);
  117. };
  118. onMounted(() => {});
  119. </script>
  120. <style scoped="scoped" lang="scss">
  121. .app-container {
  122. padding: 15px;
  123. }
  124. </style>

配合左右结构,左边树形,右边表格等,树形tree 动态自适应屏幕高度(就是多一点样式)

代码如下:

  1. <template>
  2. <div class="app-container">
  3. <el-card>
  4. <el-tree
  5. :data="treeData"
  6. :props="defaultProps"
  7. lazy
  8. :load="loadNode"
  9. node-key="id"
  10. @node-click="handleNodeClick"
  11. />
  12. </el-card>
  13. </div>
  14. </template>
  15. <script setup lang="ts" name="tasks">
  16. import { defineAsyncComponent, reactive, onMounted, toRefs, ref } from 'vue';
  17. import request from '/@/utils/requestTools';
  18. const state = reactive({
  19. title: '更新',
  20. schoolID: null,
  21. schoolList: [
  22. {
  23. id: 1,
  24. name: '小',
  25. },
  26. {
  27. id: 2,
  28. name: '大',
  29. },
  30. ],
  31. });
  32. // 定义树形数据的结构
  33. interface TreeNode {
  34. id: number;
  35. label: string;
  36. children?: TreeNode[];
  37. isLeaf?: boolean; // 用于标识是否为叶子节点(村数据)
  38. countyId?: string; // 区县ID,用于乡镇数据的加载
  39. townId?: string; // 乡镇ID,用于村数据的加载
  40. villageId?: string; // 村ID,用于组数据的加载
  41. }
  42. // 初始化树形数据,只包含区县节点
  43. const treeData = ref<TreeNode[]>([]);
  44. // 定义Tree组件的props
  45. const defaultProps = ref<any>({
  46. children: 'children',
  47. label: 'label',
  48. isLeaf: 'isLeaf', // 自定义属性,用于标识叶子节点
  49. });
  50. // 加载节点数据的方法
  51. const loadNode = async (node: any, resolve: any) => {
  52. if (node.level === 0) {
  53. // 根节点,加载所有区县数据
  54. try {
  55. // const response = await axios.get('/api/api1');
  56. // const data = response.data.data;
  57. const result: any = await request.get('/watertap/api/County/getAllCountyByCityId',{ choiseCity: '530600000000'});
  58. const data = result.data;
  59. const counties = data.map((county:any) => ({
  60. id: county.id,
  61. label: county.name,
  62. countyId: county.countyId,
  63. isLeaf: false, // 区县节点不是叶子节点
  64. }));
  65. resolve(counties);
  66. } catch (error) {
  67. console.error('加载区县数据失败:', error);
  68. resolve([]);
  69. }
  70. } else if (node.level === 1 && node.data.countyId) {
  71. // 区县节点,加载对应的乡镇数据
  72. try {
  73. // const response = await axios.get(`/api/api2`, {
  74. // params: { countyId: node.data.countyId },
  75. // });
  76. // const data = response.data.data;
  77. const result: any = await request.get('/watertap/api/town/getTownByCountyId', { countyId: node.data.countyId });
  78. const data = result.data;
  79. const towns = data.map((town:any) => ({
  80. id: town.id,
  81. label: town.name,
  82. townId: town.townId,
  83. isLeaf: false, // 乡镇节点不是叶子节点
  84. }));
  85. resolve(towns);
  86. } catch (error) {
  87. console.error('加载乡镇数据失败:', error);
  88. resolve([]);
  89. }
  90. } else if (node.level === 2 && node.data.townId) {
  91. // 乡镇节点,加载对应的村数据
  92. try {
  93. // const response = await axios.get('/api/api3', {
  94. // params: { townId: node.data.townId.replace('townId:', '') }, // 假设townId字段需要处理以匹配API要求
  95. // });
  96. const result: any = await request.get('/watertap/api/village/GetVillageByTownId', { townId:node.data.townId });
  97. // 注意:这里isLeaf应为true
  98. const data = result.data;
  99. const villages = data.map((village:any) => ({
  100. id: village.id, // 假设村数据中有id字段
  101. label: village.name, // 假设村数据中有name字段
  102. villageId:village.villageId,
  103. isLeaf: true, // 村节点是叶子节点
  104. }));
  105. resolve(villages);
  106. } catch (error) {
  107. console.error('加载村数据失败:', error);
  108. resolve([]);
  109. }
  110. } else {
  111. resolve([]);
  112. }
  113. };
  114. // 处理节点点击事件
  115. const handleNodeClick = (data: TreeNode) => {
  116. console.log('点击的节点:', data);
  117. };
  118. onMounted(() => {});
  119. </script>
  120. <style scoped="scoped" lang="scss">
  121. .app-container {
  122. padding: 15px;
  123. }
  124. </style>

欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)

评价

vue3 element plus 表单输入框放到一行

当垂直方向空间受限且表单较简单时,可以在一行内放置表单。 通过设置 inline 属性为 true 可以让表单域变为行内的表单域...

element plus 下拉列表select使用下拉列表无法选择值

下拉列表无法选择值要给一个v-model: 而且要给对,在下面对应的要有:

element plus 下拉列表默认选中有延迟

会先加载id或者编号,然后有点延迟的时间才转换成内容。 [TOC]可以这样解决,绑定的时候给中文名字,然后在改变的时候给Id...

vue elementui,vue3 element plus 文件上传时候设置其他参数后台.net接收传递额外参数图片上传

比如上传文件的时候额外传递两个select选择的值 前台前面上传文件的时候要提供默认参数很简单,el-upload绑定一个data即可...

vue3 element plus 表格使用vue3常用界面搭配vue3基础模板使用

一个简单的表格加时间搜索界面效果如下: 代码如下: &lt;template&gt; &lt;div class=&quot;app-container&quot;&g...

element plus table 表格 获取选中

官网的表格文档就有,直接一个方法就搞定了,看官网表格的文档中的方法介绍就有了 使用getSelectionRows方法即可 &lt;el-...

element plus 日期选择器 限制日期范围限制只能选择当前月份之后月份

element plus 日期选择器 可以用disabledDate来限制日期范围。例如限制只能选择当前月份以及之后的月份。 &lt;el-date-pi...

element plus 带提交内容删除确认框element plus 确认框

[TOC]Element Plus 带提交内容的删除确认框 ElMessageBox.prompt(&#39;是否确认删除数据,涉及到的数据将会被物理删除,...

vue3 element plus table+Sortable.js 行拖动,表格拖动

要先安装好Sortable.js依赖 cnpm install sortable.js 实现拖动的代码如下可以直接复制运行 &lt;template&gt; &lt;...

element plus与element ui 多选表格判断某行是否选中

element plus 多选表格判断每行是否选中@select=&quot;selectRow&quot; const selectRow = (selection: any, row: any) ...

element plus 表格 table分页状态或者条件类型切换下实现勾选记录

实现这种切换的时候勾选的复选框状态保持,如果是分页其实实现思路也一样。 实现思路:有一个缓存,存储的是选中的行,...

element plus Tree 获取选中节点父节点树获取所有选中节点

[TOC]element plus tree 获取选中节点的父节点通过 treeRef.value.getNode(data) 获取到当前节点的实例,随后通过 node.par...