赞
踩
提示:
一般侧边菜单数据都是静态、少量数据。如何实现动态可配置?
可以通过接口返回的树形结构数据动态更新菜单条目
[ { "nodeid": "777718a5-18a8-4955-928a-64b683513590", "parentid": "", "nodename": "目录1", "children": [ { "nodeid": "b278006e-cb28-4459-8f1a-e42202a96ce8", "parentid": "777718a5-18a8-4955-928a-64b683513590", "nodename": "目录1-1" } ] }, { "nodeid": "c47d3f14-9b78-46fc-ad76-52e5d4df2ef7", "parentid": "", "nodename": "目录2", "children": [ { "nodeid": "7c913e5d-0ec0-4152-b183-b001d6d92ed8", "parentid": "c47d3f14-9b78-46fc-ad76-52e5d4df2ef7", "nodename": "目录2-1" }, { "nodeid": "f1844722-ecaa-4e10-86f1-b64e3352d5ea", "parentid": "c47d3f14-9b78-46fc-ad76-52e5d4df2ef7", "nodename": "目录2-2" }, { "nodeid": "ffff9811-ac84-41d9-b4d6-bcb98bf0196f", "parentid": "c47d3f14-9b78-46fc-ad76-52e5d4df2ef7", "nodename": "目录2-3" } ] }, { "nodeid": "f59286d3-1fdc-4b7d-8fa3-c5df26e86e32", "parentid": "", "nodename": "目录3", "children": [ { "nodeid": "127eb83b-2c58-4313-96ee-aa35c01b07e6", "parentid": "f59286d3-1fdc-4b7d-8fa3-c5df26e86e32", "nodename": "目录3-1", "children": [ { "nodeid": "4749d51d-db82-4302-8f99-3c51bd1bd093", "parentid": "127eb83b-2c58-4313-96ee-aa35c01b07e6", "nodename": "目录3-1-1" }, { "nodeid": "f73a4b82-cc2a-4b5e-8015-c28478718fca", "parentid": "127eb83b-2c58-4313-96ee-aa35c01b07e6", "nodename": "目录3-1-2" }, { "nodeid": "9d38b195-e5d8-43c5-8c75-71ef52a1e1ec", "parentid": "127eb83b-2c58-4313-96ee-aa35c01b07e6", "nodename": "目录3-1-3" } ] } ] }, { "nodeid": "f4872c95-9e15-4d9a-81f8-4c04c7b275a8", "parentid": "", "nodename": "目录4", "children": [ { "nodeid": "4bbbb72c-848a-4046-97fe-40939a335299", "parentid": "f4872c95-9e15-4d9a-81f8-4c04c7b275a8", "nodename": "目录4-1" }, { "nodeid": "ccb75eba-1355-457a-8c67-a53af258e024", "parentid": "f4872c95-9e15-4d9a-81f8-4c04c7b275a8", "nodename": "目录4-2" }, { "nodeid": "bec8cc74-84e7-4909-8cdc-9650aabf75ad", "parentid": "f4872c95-9e15-4d9a-81f8-4c04c7b275a8", "nodename": "目录4-3" }, { "nodeid": "b7c6e31b-ce62-40a7-83d0-0363d48ad0a5", "parentid": "f4872c95-9e15-4d9a-81f8-4c04c7b275a8", "nodename": "目录4-4" } ] }, { "nodeid": "5e54c8f3-502a-4bed-8542-1e7208d18dad", "parentid": "", "nodename": "目录5", "children": [ { "nodeid": "4264fae0-e7e9-4d85-826e-f195e178704a", "parentid": "5e54c8f3-502a-4bed-8542-1e7208d18dad", "nodename": "目录5-1" }, { "nodeid": "01d8e744-8b29-42e1-8f59-829dcf773644", "parentid": "5e54c8f3-502a-4bed-8542-1e7208d18dad", "nodename": "目录5-2" } ] } ]
<template> <div> <div v-for="(item, index) in menuData" :key="index"> <!-- 思路: 有子元素使用el-submenu 没有子元素使用el-menu-item --> <el-submenu :index="item.nodeid" v-if="item.children && item.children.length > 0"> <template slot="title"> {{ item.nodename }} </template> //递归调用 <Menu :menuData="item.children"></Menu> </el-submenu> <el-menu-item :index="item.nodeid" v-else> {{ item.nodename }} </el-menu-item> </div> </div> </template> <script> export default { //递归 这个名称要保持驼峰转短横线链接规则 name: "Menu", props: { menuData: { type: Array, default: () => { return []; } } }, components: {}, data() { return {}; }, created() {}, mounted() {}, methods: {} }; </script> <style lang='less' scoped> </style>
<template> <div style="width:200px;height:100%"> <el-menu :default-active="defaultActive" :default-openeds="openeds" class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose" > <Menu :menuData="menuData"></Menu> </el-menu> </div> </template> <script> import Menu from "@/views/elementUi/pages/Menu"; import { uuid } from "@/common/utils.js"; export default { name: "elSlider", components: { Menu }, data() { return { menuData: [], nodePathData: [] //节点路径数据 }; }, created() {}, computed: { //默认展开的子菜单 openeds() { let openedList = []; let resList = this.nodePathData.filter(el => { return el.some(item => { return item.nodename === "目录3-1-2"; }); }); resList = resList[0]; if (resList) { resList.forEach(item => { openedList.unshift(item.nodeid); }); } console.log(JSON.stringify(openedList)); return openedList; }, //默认激活的子菜单 defaultActive() { return this.openeds[this.openeds.length - 1]; } }, mounted() { this.$axios.get("JsonFile/opitions.json").then(res => { this.menuData = res.data; console.time("x"); let nodeData = this.getNodeMsg(this.menuData, "目录3-1-2", "", []); console.log('节点数据:',JSON.stringify(nodeData)); this.nodePathData = this.getAllNodePath(this.menuData, nodeData); console.log(JSON.stringify(this.nodePathData)); console.timeEnd("x"); }); }, methods: { handleOpen(key, keyPath) { console.log(key, keyPath); }, handleClose(key, keyPath) { console.log(key, keyPath); }, /** * @author: DuHui * @description:通过节点名称 递归获取节点信息 * @param {array} data 树结构数据 * @param {string} nodename 结点名称 * @param {string} nodeid 节点id * @param {array} result 查询结果,可能会查到多个节点 格式见return * @returns {array} * [ * { * nodename, //节点名称 通过名称查找结果不唯一 * nodeid, //节点id 通过id查找结果唯一 * parentId, //父节点id * } * ... * ] */ getNodeMsg(data, nodename, nodeid, result) { data.forEach(item => { if (item.nodename === nodename || item.nodeid === nodeid) { let { nodename, nodeid, parentid } = item; result.push({ nodename, nodeid, parentid }); } if (item.children && item.children.length > 0) { this.getNodeMsg(item.children, nodename, nodeid, result); } }); return result; }, /** * @author: DuHui * @description: 获取节点路径:通过节点parentid找父节点,再通过父节点找祖父节点,以此类推 * @param {array} data 树形结构数据 * @param {object} node 当前节点对象 * @param {array} result 含有当前节点的数组 * @returns {array} 当前节点的全路径节点数组 */ getNodeFullPath(data, node, result) { //查找当前节点的父节点, let parent = this.getNodeMsg(data, "", node.parentid, []); result.push(parent[0]); if (parent[0] && parent[0].parentid) { this.getNodeFullPath(data, parent[0], result); } return result; }, /** * @author: DuHui * @description: 一个或多个节点得全路径 * @param {array} data 原始树形结构数据 * @param {array} nodeData 节点数据集含parentid * @returns {array} */ getAllNodePath(data, nodeData) { let result = []; nodeData.forEach(item => { //查找当前节点的全路径 let path = this.getNodeFullPath(data, item, [item]); result.push(path); }); return result; } } }; </script> <style lang='less' scoped> </style>
[{“nodename”:“目录3-1-2”,“nodeid”:“f73a4b82-cc2a-4b5e-8015-c28478718fca”,“parentid”:“127eb83b-2c58-4313-96ee-aa35c01b07e6”}]
3、getNodeFullPath(data, node, result):获取当前节点到根节点的路径。含有每个节点基本数据。如下:
[[{“nodename”:“目录3-1-2”,“nodeid”:“f73a4b82-cc2a-4b5e-8015-c28478718fca”,“parentid”:“127eb83b-2c58-4313-96ee-aa35c01b07e6”},{“nodename”:“目录3-1”,“nodeid”:“127eb83b-2c58-4313-96ee-aa35c01b07e6”,“parentid”:“f59286d3-1fdc-4b7d-8fa3-c5df26e86e32”},{“nodename”:“目录3”,“nodeid”:“f59286d3-1fdc-4b7d-8fa3-c5df26e86e32”,“parentid”:""}]]
4、getAllNodePath(data, nodeData) 通过nodename查到节点数据可能存在重复情况,通过循环获取所有满足节点路径即可。
3.1 、3.2 为了了解组件展开机制,使用了静态数据演示,方便理解其组件内部原理。那么如何动态实现?
到这里就很简单了 ,2.2中getNodeFullPath和getAllNodePath 这两个方法我们已经可以获取到节点路径,使用vue计算属性,做简单计算即可。
computed: { //默认展开的子菜单 openeds() { let openedList = []; let resList = this.nodePathData.filter(el => { return el.some(item => { return item.nodename === "目录3-1-2"; //要展开的节点 }); }); resList = resList[0]; if (resList) { resList.forEach(item => { openedList.unshift(item.nodeid); }); } console.log(JSON.stringify(openedList)); return openedList; }, //默认激活的子菜单 defaultActive() { return this.openeds[this.openeds.length - 1]; } },
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。