ElementPlus+Vue树型结构显示数据

一、父-子上下两级

HTML:

            <el-tree
				v-if="permission.length > 0"
				:data="permission"
				:props="props"
				:show-checkbox="true"
				expand-on-click-node
				@check="handleCheck"
				default-expand-all
			>

default-expand-all:默认全部展开;expand-on-click-node:点击展开/收缩;:show-checkbox="true":显示复选框;

JS:

			permission: [],    // 后端获得的数据
			props: {
				children: 'menu',     // 根节点包含所有子节点的字段
				label: 'title'        // 根节点标题字段
			},

二、多级

要将这个树形结构改为三级结构,你需要对数据进行处理,以确保每个节点的 children 属性包含下一级的子节点。下面是一个示例代码,展示如何将树形结构改为三级:

HTML:

<template>
  <div>
    <el-tree
      v-if="permission.length > 0"
      :data="permission"
      :props="props"
      :show-checkbox="true"
      expand-on-click-node
      @check="handleCheck"
      default-expand-all
    >
    </el-tree>
  </div>
</template>

JS:

<script>
export default {
  data() {
    return {
      permission: [], // 后端获得的数据
      props: {
        children: 'children', // 根节点包含所有子节点的字段
        label: 'title'        // 根节点标题字段
      }
    };
  },
  methods: {
    handleCheck(checkedNodes) {
      // 处理节点复选框事件,你可以在这里获取选中的节点信息
      console.log('选中的节点:', checkedNodes);
    }
  },
  async fetchData() {
    // 从后端获取树形数据
    try {
      // 替换以下代码以从后端获取数据
      // const response = await axios.get('/api/getPermissionData');
      // this.permission = response.data;

      // 模拟后端数据,树形结构包含三级
      // 即后台传入的数据得有title、children字段,children是一个List<List<Entity>>集合
      this.permission = [
        {
          title: '一级 1',
          children: [
            {
              title: '二级 1-1',
              children: [
                { title: '三级 1-1-1' },
                { title: '三级 1-1-2' }
              ]
            },
            { title: '二级 1-2' }
          ]
        },
        {
          title: '一级 2',
          children: [
            { title: '二级 2-1' },
            {
              title: '二级 2-2',
              children: [
                { title: '三级 2-2-1' }
              ]
            }
          ]
        }
      ];
    } catch (error) {
      console.error('获取树形数据失败:', error);
    }
  },
  async created() {
    // 在组件创建后获取树形数据
    this.fetchData();
  }
};
</script>

三、多选框

            <el-tree
				v-if="menu.length > 0"
				:data="menu"
				:props="props"
				:show-checkbox="true"
				node-key="id"
				expand-on-click-node
				@check="handleCheck"
				default-expand-all
				:default-checked-keys="checkedNodes"
			>
        其中:node-key="id"表示唯一标识,并且menu数据中存在id字段作为唯一标识
            checkedNodes: []    
            props: {
				children: 'menu',
				label: 'title'
			},
			menu: [],    

        handleCheck(checkNode) {
			const nodeId = checkNode.id
			console.log("id:"+nodeId)
			const index = this.checkedNodes.indexOf(nodeId)
			if (index !== -1) {
				// 如果节点 ID 已经存在于数组中,表示取消勾选,将其移除
				this.checkedNodes.splice(index, 1);

				// 取消勾选时,取消所有子节点
				this.uncheckChildren(checkNode);
			} else {
				// 否则,添加节点 ID,表示勾选
				this.checkedNodes.push(nodeId);

				// 递归勾选子节点
				this.checkChildren(checkNode)
			}
			console.log(this.checkedNodes)
		},

		// 递归勾选子节点
		checkChildren(node) {
			if (node.menu && node.menu.length > 0) {
				// 遍历子节点并递归勾选
				for (const child of node.menu) {
					const childIndex = this.checkedNodes.indexOf(child.id);
					if (childIndex === -1) {
						// 如果子节点的 ID不存在于数组中,添加它
						this.checkedNodes.push(child.id);
					}
					this.checkChildren(child); // 递归处理子节点的子节点
				}
			}
		},

		// 取消勾选时,取消所有子节点
		uncheckChildren(node) {
			if (node.menu && node.menu.length > 0) {
				// 遍历子节点并递归取消勾选
				for (const child of node.menu) {
					const childIndex = this.checkedNodes.indexOf(child.id);
					if (childIndex !== -1) {
						// 如果子节点的 ID存在于数组中,取消勾选
						this.checkedNodes.splice(childIndex, 1);
					}
					this.uncheckChildren(child); // 递归处理子节点的子节点
				}
			}
		},

四、顶部添加全选根节点

HTML部分不变,改变数据集合:

            // 参数部分            
            permission: [],
			props: {
				children: 'menu',
				label: 'title'
			},

            // 通过api获取到的值重新定义
            xxxApi.loadData().then(data => {
				this.menu = [
					{
                        id: '0',
						title: '全选',
						menu: data
					}
				]
			})

五、数据回显复选框

将回显的数据存入::default-checked-keys="checkedNodes" 中的 checkedNodes 集合中,并使用 node-key="id" 确保 default-checked-keys 属性中的 node-key 与数据对象中的节点键名一致,以使得根据数据的 node-key中的属性进行回显。

            <el-tree
				v-if="permission.length > 0"
				:data="permission"
				:props="props"
				:show-checkbox="true"
				expand-on-click-node
				@check="handleCheckB"
				default-expand-all
				:default-checked-keys="checkedNodesB"
				class="custom-tree"
				style="font-size: 15px"
				node-key="id"
			>
                   xApi.find(param).then(data => {
						this.checkedNodesB = data
						console.log(this.checkedNodesB)
					})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,你需要在项目中安装以下依赖: 1. vite:用于快速搭建现代化的 Web 应用程序。 2. vue@next:Vue 3 框架。 3. element-plus:一个基于 Vue 3 的 UI 组件库,可快速构建美观的 Web 应用程序。 4. jsplumb:一个流程图工具,可用于创建和管理复杂的流程图。 5. pinia:Vue 3 的状态管理库,用于管理应用程序的状态。 6. sortablejs:一个可拖动和排序列表的 JavaScript 库。 接下来,你需要创建一个新的 Vue 3 项目,并安装上述依赖: ``` npm init vite-app my-app cd my-app npm install npm install vue@next element-plus jsplumb pinia sortablejs ``` 然后,你需要在 `main.js` 中导入所需的依赖: ```javascript import { createApp } from 'vue' import ElementPlus from 'element-plus' import 'element-plus/lib/theme-chalk/index.css' import jsPlumb from 'jsplumb' import { createPinia } from 'pinia' import Sortable from 'sortablejs' import App from './App.vue' const app = createApp(App) app.use(ElementPlus) app.use(createPinia()) app.config.globalProperties.$jsPlumb = jsPlumb app.config.globalProperties.$Sortable = Sortable app.mount('#app') ``` 接着,你需要在 `App.vue` 中创建一个流程图组件: ```html <template> <div class="container"> <div class="sidebar"> <div class="item" @click="addNode">Add Node</div> <div class="item" @click="deleteNode">Delete Node</div> </div> <div class="main"> <div class="canvas" ref="canvas"></div> </div> </div> </template> <script> import { ref, onMounted } from 'vue' export default { name: 'App', setup() { const canvasRef = ref(null) const jsPlumbInstance = ref(null) const addNode = () => { // 添加节点 } const deleteNode = () => { // 删除节点 } onMounted(() => { // 初始化 jsPlumb jsPlumbInstance.value = $jsPlumb.getInstance({ Container: canvasRef.value, Connector: ['Bezier', { curviness: 150 }], Endpoint: ['Dot', { radius: 5 }], EndpointStyle: { fill: '#456' }, PaintStyle: { stroke: '#456', strokeWidth: 2 }, DragOptions: { cursor: 'pointer', zIndex: 2000 }, ConnectionOverlays: [ ['Arrow', { location: 1, width: 10, length: 10 }], ['Label', { label: 'FOO', id: 'label', cssClass: 'label' }], ], }) // 添加初始节点 const node = document.createElement('div') node.classList.add('node') node.setAttribute('id', 'node1') node.textContent = 'Node 1' canvasRef.value.appendChild(node) // 添加节点拖拽事件 $Sortable.create(canvasRef.value, { draggable: '.node', onEnd: (evt) => { const node = evt.item const nodeId = node.getAttribute('id') // 更新节点位置 const position = jsPlumbInstance.value.getOffset(node) const newPosition = { x: position.left, y: position.top, } // 更新节点位置到状态管理库中 }, }) }) return { canvasRef, addNode, deleteNode, } }, } </script> <style> .container { display: flex; height: 100vh; } .sidebar { width: 200px; height: 100%; background-color: #f0f0f0; display: flex; flex-direction: column; justify-content: center; align-items: center; } .main { flex: 1; height: 100%; display: flex; justify-content: center; align-items: center; } .canvas { width: 800px; height: 600px; background-color: #fff; border: 1px solid #ccc; } </style> ``` 在上面的代码中,我们使用了 `jsPlumb` 创建了一个流程图,并使用 `sortablejs` 实现了节点的拖拽和排序。我们还将节点的位置信息保存到了状态管理库中,以便在需要时进行使用。 最后,你需要在你的应用程序中添加更多的功能,例如添加连接线、删除连接线、编辑节点等等。你可以在 `jsPlumb` 的官方文档中找到更多的示例和用法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值