react的路由对比起vue来说,实用度确实8太行, 因为我之前对vue比较熟悉, 所以先入为主的觉得路由就应该按照vue那样写(本人自学的react,公司也没有用到react,也没有好大哥带我,所以一切都是自己摸索的,不对之处请指出)
在我学习的过程中发现react-router并没有像vue-router那样的子路由层级嵌套关系, 这不利于导航栏的渲染, 所以我觉得应该是一个类似vue-router那样的嵌套关系
import React,{Component} from "react";
import {Switch, Route, Redirect} from "react-router-dom"
// 路由列表
export const routerList = [
{
path: "/",
component: AsyCom(()=>import("../pages/index/index.jsx")),
mate:{icon:"HomeOutlined",title:"首页"}
},
{
path: "/home",
mate:{icon:"ControlOutlined",title:"账单"},
children:[
{
path:"",
component: AsyCom(()=>import("../pages/home/home.jsx")),
},
{
path: "/two",
component: AsyCom(()=>import("../pages/home/tow/tow.jsx")),
}
]
}
]
// 格式化列表
function formatRouterList(arr) {
let newListArr = [];
for(let i = 0; i < arr.length; i++){
if(!arr[i].children){
newListArr.push({
path:arr[i].path,
component: arr[i].component
})
}else{
// 这里解释一下防止有人疑惑, 首先需要明白引用类型和基本类型
// 基本类型是传值, 引用类型是传址, 在js中数组和对象是引用类型, 所以我传入的newListArr实际上是把内存地址传了过去, 所以修改形参可以修改实参
// 具体到这个例子中来说 我在formatRouterChildren方法中修改形参可以把传入的formatRouterList中的newListArr修改掉
formatRouterChildren(arr[i].children,newListArr,arr[i].path)
}
}
console.log(newListArr)
return newListArr;
}
// 递归解析children
function formatRouterChildren(arr,list = [],fPath) {
for(let i = 0; i < arr.length ; i++){
if(arr[i].children){
formatRouterChildren(arr[i].children,list, fPath + arr[i].path)
}else{
list.push({
path:fPath + arr[i].path,
component: arr[i].component
})
}
}
return list
}
// 利用高阶组件进行 组件懒加载
function AsyCom(loadComponent) {
return class AsyncComponent extends Component {
state = { Component: null }
// 异步加载
componentDidMount() {
if (this.state.Component !== null) {
return;
}
loadComponent()
.then(module => module.default)
.then((Component) => {
this.setState({ Component });
})
.catch((err) => {
console.error(`Cannot load component in <AsyncComponent />`);
throw err;
});
}
render() {
const { Component } = this.state;
return (Component) ? <Component {...this.props} /> : null;
}
}
}
// 注意这里仅仅是渲染了Switch组件, 外层需要套BrowserRouter或者HashRouter
export default () => {
return (
<Switch>
{
formatRouterList(routerList).map((item,index) => {
return (<Route exact path={item.path} key={index} component={item.component}/>)
})
}
<Route path={"*"} exact component={() => (
<Redirect to={"/"}/>
)}/>
</Switch>
)
}