doubleyong
管理员
管理员
  • 最后登录2025-12-02
  • 发帖数1198
  • 最爱沙发
  • 喜欢达人
  • 原创写手
  • 社区居民
  • 忠实会员
阅读:7716回复:1

[react]react 面包屑动态实现

楼主#
更多 发布于:2020-08-05 11:42
分享react 面包屑的动态实现示例:
技术点解析:
1. 在什么时候去改变面包屑的信息
componentDidMount,componentWillReceiveProps
一个是加载面包屑组件的时候,一个是组件进行跳转时,注:组件的跳转会引起props的变化,所以将面包屑生成改到props改变的事件中,即componentWillReceiveProps
2. 通过props不能获取路由数据,如location, history等
要通过props获取路由信息,请在组件中使用withRouter


3. this.props.location.pathname, 不是当前的路径名
请用this.props.history.location.pathname进行替代


4.修改了this.state里的值,但页面没有变化
请用this.setState去修改值


5. 使用了this.setState去修改值,但是页面还是没有变化
注:this.setState是异步操作,不会去等待的,需要需要修改后在进行操作,请使用回调函数的形式,如下:
     this.setState({extraBreadcrumbItems: newArr},function(){
          // 这里的代码,会在修改完成后执行
     })
6. 使用了reduce将树形的路由,展平了
参考:http://bugshouji.com/shareweb/t1281


7. 使用了pId, 来保存菜单之间的关系,数据格式如下:

/* menuId: 2,//菜单id
menuName: "用户管理理",//菜单名称
menuUrl: "/index/user",//菜单的路径,注如果子菜单要显示在父菜单中,那路径一定要有父级的路径
pathname: "userlist",//菜单路径名称,暂时没用
componentPath: "user/UserManger",//对应组件的路径
menuImgClass: 'TeamOutlined',//菜单对应的class名称,主要用于设置菜单的ICON
pId: 父级菜单的Id, 没有写 0
menuState: "0",//菜单的状态,0 有效,1无效
isContainChildren:false,//是否包含子组件中
menuChilds: []    //子菜单列表,必须是数组类型
*/

[
        {
            menuId: 2,
            menuName: "用户管理理",
            menuUrl: "/index/user",
            pathname: "userlist",
            componentPath: "user/UserManger",
            menuImgClass: 'TeamOutlined',
            pId:0,
            menuState: "0",
            isContainChildren:false,
            menuChilds: [{
                menuId: 10,
                menuName: "添加用户",
                menuUrl: "/index/adduser",
                pathname: "adduser",
                componentPath: "user/AddUser",
                menuImgClass: 'VideoCameraAddOutlined',
                pId:2,
                menuState: "0",
                isContainChildren:false,
                menuChilds: []
            },{
                menuId: 11,
                menuName: "修改用户",
                menuUrl: "/index/modifyUser",
                pathname: "modifyUser",
                componentPath: "user/ModifyUser",
                menuImgClass: 'VideoCameraAddOutlined',
                pId:2,
                menuState: "0",
                isContainChildren:false,
                menuChilds: []
            }]
        }]
]


详细代码如下:
import React from 'react'
import {Link,withRouter} from 'react-router-dom'
import { Breadcrumb } from 'antd';
import {inject,observer} from 'mobx-react'
@inject("user")
@observer
class NewBreadcrumb extends React.Component
{
    constructor(props) {
        super(props);
        this.state={
            menuList:[],
            extraBreadcrumbItems: [],
        }
    }
    //以递归的方式展平react router数组
    changeMenuList(){
        const arr = this.props.user.user.menuInfo.reduce(function f(pre,item){
            // const callee = arguments.callee //将运行函数赋值给一个变量备用
            pre.push(item)
            if(item.menuChilds && item.menuChilds.length > 0) item.menuChilds.reduce(f,pre); //判断当前参数中是否存在children,有则递归处理
            return pre;
        },[]).map((item) => {
            item.menuChilds = []
            return item
        })
        this.setState({
            menuList:arr
        },function () {
            this.buildBread()
        })
    }
    buildBread = () => {
        //清空面包屑的项
        this.setState({
            extraBreadcrumbItems:[]
        },function(){
            //1. 获取路径 名
            let pathname = this.props.history.location.pathname;
            console.log(this.props)
            let currentMenu = this.state.menuList.find((item)=>{
                return item.menuUrl === pathname
            });
            if(currentMenu && currentMenu.menuId){
                this.buildBreadItemByMenuId(currentMenu.menuId);//生成面包屑的项
            }
        });
    }
    buildBreadItemByMenuId=(menuId)=>{
        let Menu = this.state.menuList.find((item)=>{
            return item.menuId === menuId
        })
        console.log(Menu)
        if(Menu) {
            this.setState({
                extraBreadcrumbItems: [
                    (<Breadcrumb.Item key={Menu.menuUrl}>
                        <Link to={Menu.menuUrl}>
                            {Menu.menuName}
                        </Link>
                    </Breadcrumb.Item>),...this.state.extraBreadcrumbItems]
            },function () {
                if (Menu.pId !== 0) {
                    this.buildBreadItemByMenuId(Menu.pId)
                }
            })
        }
    }
    componentDidMount(){
        this.changeMenuList();
    }
    componentWillReceiveProps(){
        this.buildBread()
    }
    render() {
        return <Breadcrumb>
            <Breadcrumb.Item><Link to="/index">首页</Link></Breadcrumb.Item>
            {this.state.extraBreadcrumbItems}
            </Breadcrumb>;
    }
}
export default withRouter(NewBreadcrumb)


转载请注明出处:http://bugshouji.com/shareweb/t1284
知识需要管理,知识需要分享
wry98
贫民
贫民
  • 最后登录2020-08-11
  • 发帖数1
沙发#
发布于:2020-08-11 09:56
666
游客


返回顶部

公众号

公众号