搭建react项目时,刚开始路由的配置文件都是写死的,每写一个组件然后都需要自己去路由的配置文件中进行配置路由。其实刚开始觉得也很正常,因为动态import感觉很难实现。但是项目需求后台需要记录那些组件的路径以及路由 跳转的路径。所以就想到了哪些数据都由后台返回,前端只需要根据后台返回的路径动态的引入组件。
一开始后台返回的是完整路径,比如说自己写的组件在pages目录下,然后在routers目录中的Index.jsx中引入组件,即‘../pages/header/Header.jsx’,然后后台就给返回‘../pages/header/Header.jsx’这个路径,如图:
实际上是不行的,代码如下:
<Switch>
{this.state.RouterData && this.state.RouterData.map((item, index) => { return <Route key={index} path={item.path} component={asyncComponent(() => import(item.component))}></Route> })}
{/* 重定向 */} <Route path='/' exact render={() => ( <Redirect to="/header" /> )} />
{/* 错误路径跳转的组件 */} <Route component={ErrorView} />
</Switch>
这样引入的话会报找不到这个组件,然后就一直想是什么问题,这样写感觉也没什么问题,但是确实是报错找不到这个组件,解决方法就是后台不能返回这个完整路径,只能返回这个组件在哪个位置:比如在pages下的header文件夹中的Header.jsx,就只能返回‘pages/header/Header.jsx’,这样的话我们在引入组件时做一个字符串拼接就可以找到这个组件了,代码如下:
<Switch>
{this.state.RouterData && this.state.RouterData.map((item, index) => { return <Route key={index} path={item.path} component={asyncComponent(() => import('../' +item.component))}></Route>
})}
{/* 重定向 */} <Route path='/' exact render={() => ( <Redirect to="/header" /> )} />
{/* 错误路径跳转的组件 */} <Route component={ErrorView} /> </Switch>
注意,this.state.RouterData是后台返回来的数据然后保存在state中的,asyncComponent是异步加载组件的一个方法,代码如下:
import React from 'react'; // 这个asyncComponent函数接受一个importComponent的参数,importComponent调用时候将动态引入给定的组件。 // 在componentDidMount我们只是简单地调用importComponent函数,并将动态加载的组件保存在状态中。 // 最后,如果完成渲染,我们有条件地提供组件。如果不写null的话,也可提供一个loading,代表着组件正在渲染。 export default function asyncComponent(importComponent) { class AsyncComponent extends React.Component { constructor() { super(); this.state = { component: null } } async componentDidMount() { const { default: component } = await importComponent(); this.setState({component: component}) } render() { const C = this.state.component; return C ? <C {...this.props} /> : null; } } return AsyncComponent; }
这样就完成了异步加载组件啦,有什么还不明白的可以加我QQ: 1274668609