动态树形菜单的几种递归写法小结

VUE中递归算法实现树形菜单的写法:

<template>
    <div>
        <!-- 父组件将数据传入子组件 -->
        <tree :msg=‘msg‘ />
    </div>
</template>

<script>

export default {
    data (){  //模拟数据
        return{
            n:0,
            msg: [{name:‘北京‘,
                    sub:[{name:‘东城区‘,
                    sub:[
                        {name:‘朝阳区‘}
                    ]
                    },{name:‘西城区‘,
                        sub:[
                            {name:‘关虎屯‘}
                        ]

                    },{name:‘南城区‘},{name:‘北城区‘}]
                    }
                    ,{
                    name:‘广东‘,
                    sub:[{name:‘广州‘,
                        sub:[{name:‘越秀区‘},{name:‘白云区‘},{name:‘海珠区‘}]
                        },
                        {name:‘深圳‘,
                        sub:[{name:‘蛇口区‘},{name:‘保安区‘},{name:‘盐田区‘}]
                        },
                    ]
                    },{
                    name:‘湖北‘,
                    sub:[{name:‘武汉‘,
                        sub:[{name:‘江夏区‘},{name:"洪山区"},{name:‘江汉区‘}]
                        },
                        {name:‘天门市‘,
                        sub:[{name:‘精灵‘},{name:"小班"},{name:‘打扮‘}]
                        }]
                    }],
        }
    },
    // 注册父组件
    components: {
        tree:{
            name:‘gs‘,//递归的构造函数名

            //父组件模板,相当于构造函数return的值
            template:`
            <ul>
                <li v-for="(v,i) in msg" :key=i @click.stop.self=‘n=i‘>  //第一层的数据,点击之后,子集菜单会展开,其他子集菜单会关闭
                     {{v.name}} 

                     <gs :msg=v.sub  v-if="i==n"/>//将下一层数据传入构造函数,进行调用,形成递归,相当于自己调用自己,这一步是最关键的一步,
                </li>
            </ul>
            `,
            props: [‘msg‘],//接受父组件传的值
            data(){
                return{
                    n:0  //默认展开的菜单下标
                }
            }
        },
    }
}
</script>

JS递归方法实现:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <button onclick="fun()">递归测试</button>
    <div id="div">

    </div>

    <script>
        //模拟数据
        var data = [{
            name: 1,
            sub: [{
                name: ‘1-1‘,
                sub: []
            }]
        }, {
            name: 2,
            sub: [{
                    name: "2-1",
                    sub: [{
                            name: ‘2-1-1‘,
                            sub: []
                        }, {
                            name: ‘2-1-2‘,
                            sub: []
                        }

                    ]
                }, {
                    name: "2-2",
                    sub: [{
                        name: ‘2-2-1‘,
                        sub: []
                    }, {
                        name: ‘2-2-2‘,
                        sub: [{
                            name: ‘2-2-2-1‘,
                            sub: []
                        }]
                    }]
                }

            ]
        }, {
            name: 3,
            sub: []
        }]

        var div = document.getElementById(‘div‘)
        var str = ‘‘;

      //递归函数function list(data) {
            if (data) {
                if (data.length > 0) {
                    str += "<ul>";
                    for (let v = 0; v < data.length; v++) {
                        const item = data[v];
                        str += ‘<li>‘ + item.name;
                        list(item.sub)
                        str += ‘</li>‘;
                    }
                    str += "</ul>";
                }
            }
        }

        list(data)
        console.log(str)
        div.innerHTML = str;

//以下是递归测试函数,与树形菜单无关
        var arr = [];

        function fun() {
            var num = parseFloat(prompt("输入数字:"));
            if (typeof(num) == ‘number‘) {
                while (num > 0) {

                    arr.push(num)
                    num--;
                }
                //console.log(arr)
            }
        }
        var arrlist = [];
        // var data=[1,[2,3],[4,[5,6,[8]]],9,[10]];
        var fun3 = arr => [...arr].map((item) => Array.isArray(item) ? fun3(item) : arrlist.push(item));
        fun3(data)
            // console.log( fun3(data))
    </script>
</body>

</html>

使用VUE + element-ui   实现树形菜单:

<template>
  <div class="custom-tree-container">
    <div class="block">
      <p>使用 render-content</p>
      <el-tree
        :data="data"
        show-checkbox
        node-key="id"
        default-expand-all
        :expand-on-click-node="false"
        :render-content="renderContent"
      ></el-tree>
    </div>
    <div class="block">
      <p>使用 scoped slot</p>
      <el-tree
        :data="data"
        show-checkbox
        node-key="id"
        default-expand-all
        :expand-on-click-node="false"
      >
        <span class="custom-tree-node" slot-scope="{ node, data }">
          <span>{{ node.label }}</span>
          <span>
            <el-button type="text" size="mini" @click="() => append(data)">Append</el-button>
            <el-button type="text" size="mini" @click="() => remove(node, data)">Delete</el-button>
          </span>
        </span>
      </el-tree>
    </div>

    <button @click="getAdd">+</button>
    <button @click="getjian">-</button>
  </div>
</template>
<script>
let id = 1000;

export default {
  data() {
    const data = [
      {
        name: "北京",
        sub: [
          {
            name: "北京",
            sub: [
              { name: "东城区" },
              { name: "西城区" },
              { name: "南城区" },
              { name: "北城区" }
            ]
          }
        ]
      },
      {
        name: "广东",
        sub: [
          {
            name: "广州",
            sub: [{ name: "越秀区" }, { name: "白云区" }, { name: "海珠区" }]
          },
          {
            name: "深圳",
            sub: [{ name: "蛇口区" }, { name: "保安区" }, { name: "盐田区" }]
          }
        ]
      },
      {
        name: "湖北",
        sub: [
          {
            name: "武汉",
            sub: [{ name: "江夏区" }, { name: "洪山区" }, { name: "江汉区" }]
          },
          {
            name: "天门市",
            sub: [{ name: "精灵" }, { name: "小班" }, { name: "打扮" }]
          }
        ]
      }
    ];
   //关键部分
    let _data = function(data) {
      return data.map(v => {
        if (v.sub) {        // 遍历数据,将菜单数据赋值给 ui框架指定属性名
          v.label = v.name;
          v.children = v.sub;
          return _data(v.sub);
        }
        if (v.name && !v.sub) {
          v.label = v.name;
          return 123;
        }
      });
    };
    _data(data);
    return {
      data: JSON.parse(JSON.stringify(data)),  //将处理过的数据进行深刻隆
      data: JSON.parse(JSON.stringify(data))
    };
  },

  methods: {
    append(data) {
      const newChild = { id: id++, label: "testtest", children: [] };
      if (!data.children) {
        this.$set(data, "children", []);
      }
      data.children.push(newChild);
    },

    remove(node, data) {
      const parent = node.parent;
      const children = parent.data.children || parent.data;
      const index = children.findIndex(d => d.id === data.id);
      children.splice(index, 1);
    },

    renderContent(h, { node, data, store }) {
      return (
        <span class="custom-tree-node">
          <span>{node.label}</span>
          <span>
            <el-button
              size="mini"
              type="text"
              on-click={() => this.append(data)}
            >
              Append
            </el-button>
            <el-button
              size="mini"
              type="text"
              on-click={() => this.remove(node, data)}
            >
              Delete
            </el-button>
          </span>
        </span>
      );
    },
    getAdd() {
      this.$store.commit("increment");
      console.log("我是加法" + this.$store.state.count);
    },
    getjian() {
      this.$store.commit("jian", 2);
      console.log("我是加Z法" + this.$store.state.count);
    }
  },
  mounted() {
    console.log(this.$store.state.count);
  }
};
</script>

<style>
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
</style>

原文地址:https://www.cnblogs.com/wxyblog/p/11618686.html

时间: 2024-10-09 07:14:20

动态树形菜单的几种递归写法小结的相关文章

利用多叉树实现Ext JS中的无限级树形菜单(一种构建多级有序树形结构JSON的方法)

一.问题研究的背景和意义 目前在Web应用程序开发领域,Ext JS框架已经逐渐被广泛使用,它是富客户端开发中出类拔萃的框架之一.在Ext的UI控件中,树形控件无疑是最为常用的控件之一,它用来实现树形结构的菜单.TreeNode用来实现静态的树形菜单,AsyncTreeNode用来实现动态的异步加载树形菜单,后者最为常用,它通过接收服务器端返回来的JSON格式的数据,动态生成树形菜单节点.动态生成树有两种思路:一种是一次性生成全部树节点,另一种是逐级加载树节点(利用AJAX,每次点击节点时查询下

Winform开发主界面菜单的动态树形列表展示

我在之前很多文章里面,介绍过Winform主界面的开发,基本上都是标准的界面,在顶部放置工具栏,中间区域则放置多文档的内容,但是在顶部菜单比较多的时候,就需要把菜单分为几级处理,如可以在顶部菜单放置一二级菜单,这种方式在一般功能点不算太多的情况下,呈现的界面效果较为直观.也较为美观.不过随着一些系统功能的增多,这种方式可能就会显得工具栏比较拥挤,那么我们是否可以在左侧放置一个树形列表,这样通过树形列表的收缩折叠,就可以放置非常多的菜单功能了. 1.菜单的树形列表展示 一般情况下,树形列表的显示可

用C#从数据库动态生成AdminLTE菜单的一种方法

用C#从数据库动态生成AdminLTE菜单的一种方法 当前的应用设计风格趋于Flat扁平化,很多基于BootStrap实现了很多UI非常漂亮的管理界面(Bootstrap admin template). 此核心文件开源在Github:https://github.com/JackWangCUMT/AdminLTE-Menu-Generate.首先看一下主界面: 查看左边导航的菜单html结构(下面代码有错误,HTML自定义属性直接用空格进行分割,而不是,号进行分割,不然jquery获取定义属性

zTree 从数据库中动态加载树形菜单

这几天做动态菜单用到了这个插件,目前用的很广泛的一个开源框架,最新发布的QUI框架就是用这个插件开发的菜单部分,因此还是很值得深入研究和学习,通过使用感觉功能很丰富,好多函数不用自己开发和编写,官网上有很详尽的API可以参考,用着算顺手但学习使用的过程中也遇到了一些困难,听过反复测试和查资料都理解了,但也在思考一个问题,怎么样才能使得最快的时间从接触一个新东西到灵活掌握的程度? 这个不仅仅是一个树形结构的菜单,每个节点左边可以有一个复选框,看了看也挺简单的,只需要在setting里面配置一个ch

EasyUI创建异步树形菜单和动态添加tab页面

创建异步树形菜单 添加树形菜单的ul标签 <ul class="easyui-tree" id="treeMenu"> </ul> 写js代码,对菜单的ul标签元素使用tree函数 $('#treeMenu').tree({ url:'tree_data.json' //url的值是异步获取数据的页面地址 }); 写用来异步获取数据的页面(tree_data.json页面).返回的需是Json值(此处用数组代替从数据库获取的数据,以省略连接数

c#从数据库读取数据动态生成树形菜单

页面: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebTree.aspx.cs" Inherits="Tree.WebTree" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/

WEB开发中前后台树形菜单的展示设计

在WEB开发中经常需要进行树形菜单的展示,本例通过不同角度的总结了如下三种实现方式: 通过JS的递归实现前端菜单DOM的动态创建 通过JSP的include指令结合JSTL表达式语言递归实现菜单的展示 通过扩展JSP的标签在后端实现菜单的DOM节点并响应给前端展示 针对第一种方法,可以采用JS的相关组件,或者使用JS的递归调用将服务端相应的数据组装成DOM节点内容,动态添加到菜单的Container中,网上的例子较多,在此不再赘述,本例就后两种方案进行讲解. 通过JSP的include指令结合J

生成树形菜单

题记------学习别人的精髓,并加以总结,消化吸收,这就是提高!!! 动态生成树形菜单,前台用easyui实现,非常简单不赘述,主要给出后台java的逻辑代码 1 package com.gongli.util.entity.treeMenu; 2 3 4 5 /* 6 * 用于封装树形菜单,无具体表与之对应,根节点为-1,节点0,然后父节点0,节点001,父节点001,节点001001,001002,001...依次类推 7 */ 8 public class TreeMenu { 9 pr

用dtree实现树形菜单 dtree使用说明

http://www.jb51.net/article/28566.htm 准备工作: 请从脚本之家http://www.jb51.net/jiaoben/31974.html下载dtree.zip文件 dtree.zip压缩包介绍: dtree是一个由JavaScript编写成的简单的树形菜单组件,目前免费并且开源. 目前有很多的树形菜单组件(比如ext),dtree是一种简单易懂的js组件, 不需要复杂的操作即可生产,同时支持动态从数据库引入数据 解压后有以下几部分: img文件夹: 包含树