• react.js三级菜单

    2016-11-15 17:00:11
    html:    Demo   ...import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import { DatePicker } from 'antd'; import { Menu,

    html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Demo</title>
      <link rel="stylesheet" href="index.css" />
    </head>
    <body>


    <div id="root"></div>


    <script src="common.js"></script>
    <script src="index.js"></script>


    </body>
    </html>

    js:

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import { DatePicker } from 'antd';
    import { Menu, Dropdown, Icon } from 'antd';
    const SubMenu = Menu.SubMenu;


    const menu = (
      <Menu>
        <Menu.Item>1</Menu.Item>
        <Menu.Item>2</Menu.Item>
        <SubMenu title="3">
          <Menu.Item>3.1</Menu.Item>
          <Menu.Item>3.2</Menu.Item>
          <Menu.Item>3.3</Menu.Item>
        </SubMenu>
        <SubMenu title="4">
        <SubMenu title="4.1">
          <Menu.Item><a href="https://www.baidu.com">4.1.1</a></Menu.Item>
          <Menu.Item>4.2.2</Menu.Item>
          <Menu.Item>4.3.3</Menu.Item>
        </SubMenu>
          <Menu.Item>4.2</Menu.Item>
          <Menu.Item>4.3</Menu.Item>
        </SubMenu>
      </Menu>
    );


    ReactDOM.render(
      <Dropdown overlay={menu}>
        <a className="ant-dropdown-link" href="#">
          Cascading menu <Icon type="down" />
        </a>
      </Dropdown>
    , document.getElementById('root'));


    展开全文
  • 在开发CMS(内容管理系统)系统时,一般都会用到一个侧边栏或者顶部的二级或者三级菜单,当点击或者鼠标悬浮时,菜单能够随之展开或收起。 本文纯粹为了练习一下react,因此我会在react环境下实现这么一个小组件...

    在开发CMS(内容管理系统)系统时,一般都会用到一个侧边栏或者顶部的二级或者三级菜单,当点击或者鼠标悬浮时,菜单能够随之展开或收起。

    本文纯粹为了练习一下react,因此我会在react环境下实现这么一个小组件:它假设了菜单数据来自于网络请求,并且仅实现无限分级菜单的核心功能(父子关系,展开与收起),至于样式则不是关注的重点。

    分析&设计

    既然要实现一个动态生成的无限分级菜单,最简单的切入思路就是分析一个静态的菜单:其DOM树是怎样构成的?

    下面是一个典型的HTML结构:

    <ul>
        <li>
              <h1>菜单1</h1>
              <ul>
                      <li>
                              <h1>菜单1-1</h1>
                              <ul></ul>
                      </li>
              </ul>
        </li>
        <li>
              <h1>菜单2</h1>
              <ul>
                      <li>
                              <h1>菜单2-1</h1>
                              <ul>
                                         <li>
                                               <h1>菜单2-1-1</h1>
                                               <ul></ul>
                                        </li>
                              </ul>
                      </li>
              </ul>
        </li>
    </ul>

    这是一个3级菜单,我们需要仔细观察它的构成规律:

    • 首先<ul>代表了一个菜单列表,它里面包含了若干<li>代表其中1个菜单项
    • 每个<li>菜单项至少包含自己的标题,其次也应包含它下面的子菜单列表(也就是另一个<ul>)。

    上述2个规则基本就是分级菜单的核心构思了,通过一个比较白话的描述可以这么理解:

    要画一个菜单列表,那么就要去画它的每一个菜单项。

    要画一个菜单项,那么就要画出标题,然后去画它的子菜单列表。

    如果你反复的读上面的话,你可以感受到一种『递归的味道』。

    没错,要根据菜单数据动态的画出一个无限分级的菜单是要用递归算法的。有意思的是,递归算法本身是深度优先的,而这恰好满足我们从上至下从外至内顺序追加HTML标签,从而最终构成完整的DOM树的编程思路。

    数据结构&算法

    程序设计=数据结构+算法。

    因此,先用一个合理的数据结构来描述之前我们的构思,之后基于数据结构进行算法的实现,最终形成程序,这是我们正确的编程思路。

    通常,菜单结构是服务端拼装的,它描述了菜单的父子和顺序关系,并且每个菜单拥有自己的唯一ID,这些都体现在我的render()方法中:

        render() {
            let data = [
                {
                    menuId: 1,
                    name: '员工管理',
                    children: [
                        {
                            menuId: 3,
                            name: '添加员工',
                            children: []
                        },
                        {
                            menuId: 4,
                            name: '删除员工',
                            children: [
                                {
                                    menuId: 6,
                                    name: '按姓名删除',
                                    children: []
                                },
                                {
                                    menuId: 7,
                                    name: '按工号删除',
                                    children: []
                                }
                            ]
                        }
                    ],
                },
                {
                    menuId: 2,
                    name: '工资管理',
                    children: [
                        {
                            menuId: 5,
                            name: '修改工资',
                            children: []
                        }
                    ],
                },
            ];
    
            return (
                <div>
                    {this.generateMenu(data)}
                </div>
            );
        }

    最外层是一个菜单列表(Array),每个菜单项(Object)里有自己的标题,唯一ID,以及子菜单列表(Array)。

    在render()方法里调用了我实现的递归算法generateMenu(data),根据上述数据结构和原理递归的生成了DOM树:

        /**
         * 递归生成菜单
         * @param menuObj
         * @returns {Array}
         */
        generateMenu(menuObj) {
            let vdom = [];
    
            if (menuObj instanceof Array) {
                let list = [];
                for (var item of menuObj) {
                    list.push(this.generateMenu(item));
                }
                vdom.push(
                    <ul key="single">
                        {list}
                    </ul>
                );
            } else {
                vdom.push(
                    <li key={menuObj.menuId}>
                        <h1 onClick={this.onMenuClicked}>
                            {menuObj.name}
                        </h1>
                        {this.generateMenu(menuObj.children)}
                    </li>
                );
            }
            return vdom;
        }
    • 第1个分支判断:如果当前对象是菜单列表(Array类型),那么应生成1个新的<ul>元素,并且递归画出每一个菜单项(Object类型)。
    • 第2个分支判断:如果当前对象是菜单项(Object类型),那么应生成1个新的<li>元素,填充1个<h1>作为标题,其次递归画出它的子菜单列表。

    最后,为了实现点击鼠标展开和收起菜单,我为每一个<h1>标签注册了onClick事件,当它们被点击时找到<h1>的兄弟<ul>元素(利用jquery搞定),修改其CSS display属性即可实现展现和隐藏其子菜单列表的效果了。

    体验效果(react组件)

    查看代码:https://github.com/owenliang/react/tree/master/component/MenuPage

    查看demo:http://yuerblog.cc/wp-content/uploads/2016/11/output/#/menu-page

    demo可以点击体验展开 or 收起


    展开全文
  • /** * Sample React Native App * https://github.com/facebook/react-native */ import React, { Component } from 'react'; import { StyleSheet, Text, ScrollView, I

    menu

    /**
    * Sample React Native App
    * https://github.com/facebook/react-native
    */

    import React, {
      Component
    } from 'react';
    import {
      StyleSheet,
      Text,
      ScrollView,
      Image,
      ListView,
      TouchableOpacity,
      View,
      InteractionManager,
      RefreshControl,
      Navigator,
    } from 'react-native';

    import {
      // Admin,
    } from '../actions/adminAction';
    import Common from '../common/common';
    import Loading from '../common/loading';
    import LoadMoreFooter from '../common/loadMoreFooter';
    import HeaderView from '../common/headerView';
    import BaseComponent from '../common/baseComponent';
    import Icon from 'react-native-vector-icons/FontAwesome';

    let titleName = '管理';
    let list = ['一级菜单一', '一级菜单二', '一级菜单三'];
    let tag = "";
    let list2 = ['submenu1', 'submenu2', 'submenu3'];

    class Admin extends BaseComponent {

      constructor(props) {
        super(props); //这一句不能省略,照抄即可
        // debugger
        this.state = {
                listExpand:[false,false,false],//true表示有数据更新
        };
      }


      renderMenuList(list) {
        return list.map((item, i) => this.renderItem(item, i));
      }

      onPressItem(i){
        let l=this.state.listExpand;
        l[i]=!l[i];
        this.setState({listExpand:l});
      }
      renderItem(item, i) {
        return (
          //<View key={i}><Text>{item}</Text></View> caret-down
          <View key={i}>
          <TouchableOpacity
                    activeOpacity={0.75}
                    onPress={this.onPressItem.bind(this,i) }              
          >
          <View style={styles.itemContainer} >
            <Icon color="gray" size={30} name={this.state.listExpand[i]?'caret-down':'caret-right'} />
            <Text>{item}</Text>       
          </View>
          </TouchableOpacity>
          {this.state.listExpand[i]?this.renderSubMenuList(list2):null}
          </View>
         
        );
      }
      renderSubMenuList(list2) {
        return list2.map((item, i) => this.renderSubItem(item, i));
      }
      renderSubItem(item, i) {
        return (
          //<View key={i}><Text>{item}</Text></View>
          <View style={styles.itemContainer} key={i}>
            <Text>{item}</Text>
            <Icon color="gray" size={30} name='angle-right' />
          </View>
        );
      }

      render() {
        //解构获取上一层的属性Home,rowDate,来自于HomeContainer
        //const { Home,rowDate } = this.props;
        // tag = rowDate;
        // console.log(this.props);
        // debugger
        //let homeList = Home.HomeList;
       

        return (
          <View>
            <HeaderView
              titleView={titleName}
              leftIcon={tag ? 'angle-left' : null}
              />
            <ScrollView contentContainerStyle={styles.contentContainer}>
              {this.renderMenuList(list)}
            </ScrollView>
          </View>
        );
      }

    }

    const styles = StyleSheet.create({
      contentContainer: {
        paddingBottom: 20,
      },
      center: {
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center',
      },
      itemContainer: {
        width: Common.window.width - 20,
        height: 50,
        paddingLeft: 10,

        paddingRight: 10,
        flexDirection: 'row',
        justifyContent: 'space-between',
        alignItems: 'center',
        backgroundColor: 'white',
        borderBottomColor: '#ccc',
        borderBottomWidth: 0.5,

      },
    });

    module.exports = Admin;




    ---------------------------

    headerView.js



    /**
     * Created by ljunb on 16/5/8.
     * 导航栏标题
     */
    import React from 'react';
    import {
        StyleSheet,
        View,
        Text,
        Image,
        TouchableOpacity,
    } from 'react-native';
    import Icon from 'react-native-vector-icons/FontAwesome';
    import Common from '../common/common';


    export default class Header extends React.Component {


        render() {


            let NavigationBar = [];


            // 左边图片按钮
            if (this.props.leftIcon != undefined) {
                NavigationBar.push(
                    <TouchableOpacity
                        key={'leftIcon'}
                        activeOpacity={0.75}
                        style={styles.leftIcon}
                        onPress={this.props.leftIconAction}
                        >
                        <Icon color="white" size={30} name={this.props.leftIcon} />
                    </TouchableOpacity>
                )
            }


            // 标题,没有用!?
            // if (this.props.title != undefined) {
            //     NavigationBar.push(
            //         <Text key={'title'} style={styles.title}>{this.props.title}</Text>
            //     )
            // }


            // 自定义标题View
            if (this.props.titleView != undefined) {
                // let Component = this.props.titleView;


                NavigationBar.push(
                    <View key={'titleView'} style={styles.titleViewContainer}>
                        <Text style={styles.titleView}>{this.props.titleView}</Text>
                    </View>
                )
            }




            return (
                <View style={styles.navigationBarContainer}>
                    {NavigationBar}
                </View>
            )
        }
    }


    const styles = StyleSheet.create({


        navigationBarContainer: {
            width: Common.window.width,
            marginTop: 0,
            flexDirection: 'row',
            height: 44,
            // justifyContent: 'center',
            // alignItems: 'center',
            backgroundColor: '#2e8b57',
            borderBottomColor: '#ccc',
            borderBottomWidth: 0.5,
            // backgroundColor: 'white'
        },


        title: {
            fontSize: 15,
            marginLeft: 15,
        },
        titleViewContainer: {
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center',
        },
        titleView: {
            fontSize: 15,
            color: 'white'
        },
        leftIcon: {
            width: 40,
            justifyContent: 'center',
            alignItems: 'center',
        },
    })

    展开全文
  • react style: 二级菜单

    2019-06-22 07:26:18
    1、样式 @import "../../styles/varibles"; .app-sidebar { overflow: hidden; width: 180px; > ul > li { position: relative; font-size: $font-lg; border-bottom: $border;......

    1、样式

    @import "../../styles/varibles";
    
    .app-sidebar {
      overflow: hidden;
      width: 180px;
    
      > ul > li {
        position: relative;
        font-size: $font-lg;
        border-bottom: $border;
        border-right: $border;
        border-left: $border;
    
        &:first-child {
          border-top: $border;
          border-top-right-radius: $border-radius;
          border-top-left-radius: $border-radius;
        }
    
        &:last-child {
          border-bottom-right-radius: $border-radius;
          border-bottom-left-radius: $border-radius;
        }
      }
    
      .active {
        border-left: 3px solid $primary-color;
        background-color: $item-active-bg-color;
        a {
          font-weight: bold;
        }
      }
    
      .nav-item {
        .item-name {
          margin-right: 30px;
          height: 50px;
          line-height: 50px;
        }
        .anticon {
          position: absolute;
          height: 50px;
          line-height: 50px;
          left: 7px;
          font-size: $font-sm;
          color: $title-color;
        }
      }
    
      &.is-open {
        .anticon {
          color: $primary-color;
        }
        .nav-item-content {
          color: $title-color;
          font-weight: bold;
        }
      }
      &:hover {
        .anticon,
        .nav-item-content {
          color: $primary-color;
        }
      }
      &:active {
        .nav-item-content {
          color: $primary-color;
          font-weight: bold;
        }
      }
      .sub-menu {
        border-top: none;
        font-size: $font-sm;
    
        .item-name {
          height: 40px;
          line-height: 40px;
        }
    
        .child-nav-item.active {
          .item-name {
            color: $primary-color;
            font-weight: bold;
          }
        }
      }
    }

    2、js文件

    import React from "react";
    import {withRouter} from "react-router-dom";
    import {Icon} from "antd";
    import _ from "lodash";
    const menus = [];
    const currentState = '';
    
    class Sidebar extends React.Component {
    
        componentDidMount() {
            const defaultNavItem = this.getDefaultNavItem();
            if (defaultNavItem === undefined) {
                this.props.history.replace('/forbidden');
                return;
            }
            this.setActiveNavItem(defaultNavItem);
            this.openNavItem(defaultNavItem);
            if (this.hasChildItems(defaultNavItem)) {
                this.setActiveChildNavItem(defaultNavItem.childItems);
            }
        }
    
        getDefaultNavItem() {
            const currentState = currentState;
            return _.find(menus, function (navItem) {
                if (navItem.state === currentState || _.some(navItem.childItems, {state: currentState})) {
                    return navItem;
                }
            })
        }
    
        setActiveNavItem(navItem) {
            if (this.hasChildItems(navItem)) {
                this.clearParentActiveStatus();
            }else {
                this.clearActiveStatusWithChildItems();
                navItem.isActive = true;
                if (!!navItem.state) {
                    this.props.history.replace(navItem.state);
                }
            }
        }
    
        setActiveChildNavItem(childNavItems) {
            const currentState = currentState;
            this.clearActiveStatusWithChildItems();
            if (_.isArray(childNavItems)) {
                childNavItems.forEach(function (navItem) {
                    navItem.isActive = navItem.state === currentState;
                });
            }else {
                childNavItems.isActive = true;
            }
        }
    
        openNavItem(navItem) {
            navItem.isOpen = this.hasChildItems(navItem);
            this.forceUpdate();
        }
    
        onOpenNavItem(navItem) {
            if (this.hasChildItems(navItem)) {
                navItem.isOpen = !navItem.isOpen;
            }else {
                navItem.isOpen = false;
            }
            this.forceUpdate();
        }
    
        clearParentActiveStatus() {
            menus.forEach(function (navItem) {
                navItem.isActive = false;
            })
        }
    
        clearActiveStatusWithChildItems() {
            menus.forEach(function (navItem) {
                navItem.isActive = false;
                navItem.childItems.forEach(function (childItem) {
                    childItem.isActive = false;
                })
            })
        }
    
        hasChildItems(navItem) {
            return !!navItem.childItems && navItem.childItems.length > 0;
        }
    
        menuIcon(navItem) {
           return <Icon type={navItem.isOpen ? 'caret-down' : 'caret-right'}/>
        }
    
        openOrActiveClass(navItem) {
            const basic = "nav-item";
            const openClass = navItem.isOpen ? "is-open" : "";
            const activeClass = navItem.isActive ? "active" : "";
            return basic + " " + openClass + " " + activeClass;
        }
    
        activeClass(navItem) {
            const basic = "child-nav-item";
            const activeClass = navItem.isActive ? "active" : "";
            return basic + " " + activeClass;
        }
    
        render() {
            return (
               <aside className="app-sidebar">
                   <ul className="list-unstyled menu">
                       {
                           menus.map((navItem, index) => {
                               return (
                                   <li key={'li_'+index} className={this.openOrActiveClass(navItem)}>
                                       <span key={'span' + index}
                                             className="item-name nav-item-content"
                                             onClick={() => {
                                                 this.setActiveNavItem(navItem);
                                                 this.onOpenNavItem(navItem)
                                             }}>
                                           {this.hasChildItems(navItem) ? this.menuIcon(navItem) : null}
                                           {navItem.name}
                                       </span>
                                       {
                                           navItem.isOpen ?
                                               <ul key={'subMenu_ul'} className="list-unstyled sub-menus">
                                                   {
                                                       navItem.childItems.map((childItem, itemIndex) => {
                                                           return (
                                                               <li key={'submenu_li_' + itemIndex}
                                                                   className={this.activeClass(childItem)}
                                                                   onClick={() => {
                                                                       this.setActiveChildNavItem(childItem);
                                                                       this.setActiveNavItem(childItem)
                                                                   }}>
                                                                   <a className="item-name">{childItem.name}</a>
                                                               </li>
                                                           )
                                                       })
                                                   }
                                               </ul> : null
                                       }
                                   </li>
                               )
                           })
                       }
                   </ul>
               </aside>
            )
        }
    }
    
    export default withRouter(Sidebar);

    3、数据

    [
      {
        "description": "userCanGetMenus",
        "request": {
          "method": "GET",
          "uri": "/api/menus"
        },
        "response": {
          "status": 200,
          "json": {
            "id": "DEMO0000",
            "fatherId": "00000000",
            "state": "process",
            "name": "运营流程",
            "childItems": [
              {
                "id": "DEMO1000",
                "fatherId": "DEMO0000",
                "state": "/process.personal-task-pool",
                "name": "个人任务池",
                "childItems": []
              },
              {
                "id": "DEMO2000",
                "fatherId": "DEMO0000",
                "state": "/process.common-task-pool",
                "name": "公共任务池",
                "childItems": []
              },
              {
                "id": "DEMO1000",
                "fatherId": "DEMO0000",
                "state": "/process.launch",
                "name": "流程发起",
                "childItems": []
              },
              {
                "id": "DEMO1000",
                "fatherId": "DEMO0000",
                "state": "/process.search",
                "name": "流程查询",
                "childItems": []
              }
            ]
          }
        }
      }
    ]

     

    转载于:https://www.cnblogs.com/Nyan-Workflow-FC/p/9332280.html

    展开全文
  • 1.在整个项目制作之前,选择了antd作为react的组件库 所以在做菜单时,选择了layout布局样式 <Layout> <Header> <HeaderMenu headlist={this.state.headlist} user={this.props.userNam...

    1.在整个项目制作之前,选择了antd作为react的组件库

    所以在做菜单时,选择了layout布局样式

    <Layout>
                    <Header>
                        <HeaderMenu headlist={this.state.headlist} user={this.props.userName} headname={this.state.headname} 
                            leftMenu={this.leftMenu}//子页面传入的方法数据
                        />
                    </Header>
                    <Layout>
                        <Sider>
                            <LeftMenu leftlist={this.state.leftlist} />
                        </Sider>
                        <Content style={{margin:'28px 20px 0px 20px'}}>
                            {this.props.children}  
                        </Content>
                    </Layout>
                    
                    
                </Layout>

    这样就有了一个整体的布局样式

    2.无限层级菜单制作

    顶部菜单和左边菜单,我都做成了一个组件<HeaderMenu/>,<LeftMenu/>

    顶部菜单放置主要菜单,左边放置菜单项及子菜单项......等

    在登陆的时候就读取了菜单的接口,返回了菜单的树结构对象数据

    利用这个树结构构建

    menuId: "0"
    name: "开放平台后台管理系统"
    sort: "0"
    sub: [,…]
    0: {menuId: "100001100000000000", parentId: "0", name: "运营管理", path: "/operation/product", sort: "100",…}
    menuId: "100001100000000000"
    name: "运营管理"
    parentId: "0"
    path: "/operation/product"
    sort: "100"
    sub: [{menuId: "100001100100000000", parentId: "100001100000000000", name: "产品订阅审核",…},…]
    0: {menuId: "100001100100000000", parentId: "100001100000000000", name: "产品订阅审核",…}
    1: {menuId: "100001100200000000", parentId: "100001100000000000", name: "用户管理",…}
    2: {menuId: "100001100300000000", parentId: "100001100000000000", name: "实名认证审核",…}
    3: {menuId: "100001100400000000", parentId: "100001100000000000", name: "CFCA证书申请审核",…}
    4: {menuId: "100001100500000000", parentId: "100001100000000000", name: "系统公告", path: "/operation/notice",…}
    1: {menuId: "100001200000000000", parentId: "0", name: "接入管理", path: "/portalBack/business_management",…}
    .................

    3.遍历该数据结构,获取主菜单使用的antd的menu组件,

    <Menu onClick={this.handleClick.bind(this)} selectedKeys={[this.state.current]} mode="horizontal">
                            {
                                this.props.headlist.map(function (item, index) {
                                    return (
                                        <Menu.Item key={item.path} data={item.sub}>
                                            {item.name}
                                        </Menu.Item>
                                    );
                                })
                            }
                        </Menu>

    将菜单项的数据包裹在一个属性data当中,当点击菜单的时候,执行handleClick方法,

    handleClick = (e) => {
            this.setState({
                current: e.key,//设置点击菜单选择时的选择项
                
            });
      localStorage.setItem('topMenuSelect', e.key);//用localStorage存入确定跳转页面后菜单的选择项
     this.props.leftMenu(e.item.props.data);//将菜单项数据传向父页面方法,用于在点击每个菜单的时候,更新左边菜单项,
        }

    4.左边菜单组件的编写

    <Menu onClick={this.handleClick.bind(this)}
                        style={{ width: 201, borderBottom: '1px solid #2E3243', fontSize: 14, color: '#C3CEE0', background: 'none', overflow: 'hidden', borderBottom: '0px' }}
                        selectedKeys={[localStorage.getItem('leftMenuSelect')]}//将选择的菜单项存入localStorage是用于切换页面刷新页面数据后确定点击的菜单项
                        defaultOpenKeys={['sub1']}
                        mode="inline"
                    >
                        {
                            this.props.leftlist.map(function (item, index) {
                                if (item.sub != undefined) {
                                    this.cress(item.sub);//如果有菜单项就执行这个方法去循环遍历出菜单,如此无限层级就完成了
                                } else {
                                    return (
                                        <Menu.Item key={item.path} data={item}>
                                            <Icon type="menu-unfold" theme="outlined" style={{ marginRight: 14 }} />
                                            {item.name}
                                        </Menu.Item>
                                    );
                                }
                            })
                        }
                    </Menu>
        
      handleClick = (e) => {
        let bbq = [];
        bbq.push(e.key);
        localStorage.setItem('leftMenuSelect', bbq);//存入选择的菜单项到localStorage中,用于确定页面跳转后的所属菜单页面
        this.props.history.push(e.item.props.data.path);//跳转到事先写好router路径的页面, path里面是前后端对接的地址数据,
      }
     cress(sub, name) {//递归出所有菜单项,及子菜单等
            return (
                <SubMenu title={
                    <span className="submenu-title-wrapper">
                        <Icon type="menu-unfold" theme="outlined" style={{ marginRight: 14 }} />
                        {name}
                    </span>
                }>
                    {
                        sub.map((item) => {
                            if (item.sub != undefined) {
                                this.cress(item.sub, item.name);
                            } else {
                                return (
                                    <Menu.Item key={item.path}>{item.name}</Menu.Item>
                                );
                            }
                        })
                    }
                </SubMenu>
            );
        }

    如此,无限层级菜单

     

    转载于:https://www.cnblogs.com/sunshineForFuture/p/10342657.html

    展开全文
  • React递归菜单

    2019-07-20 17:21:30
    React加antd实现动态递归菜单 前提: 1、 import antd 的 菜单组件 2、定义好子节点菜单const { SubMenu } = Menu; 可以直接参考最后的完整代码。 首先我的菜单数据是这样的 menuList = [ { title: '父级菜单1', ...
  • 直接上代码 以下是官网的例子 import { Menu, Icon } from 'antd';...class Sider extends React.Component { // submenu keys of first level //带下拉的submenu rootSubmenuKeys = ['sub1', 'sub2'...
  • 最近在项目中面临导航特别多的情况,需要将导航存到数据库里面,然后前端从接口那数据渲染生成。...3、在route里面找到对应的路径即可 转载于:https://www.cnblogs.com/ryt103114/p/7060887.html...
  • 关于布局,我们以偏向管理系统的风格为例,采用上左右布局,即:上放置logo,账户信息等公共数据,左放置菜单分类,多级导航等,右放置主体业务内容等。 1 先来改造layout/layout.js,增加主体布局,并且判断是否是...
  • 1、实现效果折叠菜单的层级...只是第一层级如果有子层级则呈现可展开图标,可进一步加载呈现下一层级菜单内容,否则没有是否可继续加载呈现下一层级,原理同上3、代码实现分步解析(1)第一步:依赖组件本效果的实...
  • 首先是给路径建表,存在数据库里 SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for `route_config` -- ---------------------------- DROP TABLE IF EXISTS `route_config`;...
  • 随着侧边栏的东东越来越多…本来不考虑的三级菜单,也需要考虑进去了; 一开始都是手动map去遍历对应的组件, 相关的的组id这些也是简单的判断下children就返回一个值; 有兴趣的瞧瞧 分析所需 路由规格统一,层级不定,...
  • 上个版本 :React 折腾记 - (3) 结合Mobx实现一个比较靠谱的动态tab水平菜单,同时关联侧边栏 效果图 功能点 在上个版本的功能的基础上梳理,剔除一些BUG,基本都会触发联动 重定向 关闭单一标签/关闭...
  • Index.jsx import '../common/lib'; import App from '../component/App'; import ReactDOM from 'react-dom';...import React from 'react'; import { Link } from 'react-router'; import { Router, Route, Redire
  • <!DOCTYPE html><html> <head> <meta charset="UTF-8" /> <...Hello React</title> <script src="https://unpkg.com/react@15.3.2/dist/react.js"></scr...
  • 最近要做一个组织机构树的树级菜单展示,UI框架使用的是Ant Design,这不正好可以使用Tree组件,如图示 奈何领导说太丑,指明要换成类似Menu形式的树形菜单,如图示 于是乎,有两种修改方案 先考虑改造Tree...
  • 二级导航–鼠标悬浮菜单出现二级菜单 &lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head &gt; &lt;meta charset="utf-8"&gt; &lt;title&gt;鼠标悬浮菜单出现二...
  • 本教程总共6篇,每日更新一篇,请关注我们!你可以进入历史消息查看以往文章,也敬请期待我们的新文章! ...1、React第三方组件1(路由管理之Router的使用①简单使用)---2018.01.22 ...3React第三方组件1(路由管理之Rou
1 2 3 4 5 ... 20
收藏数 3,450
精华内容 1,380
热门标签