|
分享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 |
|
|