React-Router 嵌套路由(路由嵌套路由)

2020-03-12  本文已影响0人  爱吃豆包

目前使用的版本

"react-router-dom": "^5.1.2",
示例图1 示例图2

先定义页面

Topic.js, About.js, Topic.js, A.js, B.js (将里面的文字做相应的替换)

import React from 'react'

export default class Topic extends React.Component {
    render() {
        return (
            <>
                <div>
                    Topic页面
                </div>
            </>
        )
    }
}

Home2.js

import React from 'react'
import { Link } from 'react-router-dom'

export default class Home extends React.Component {
    render() {
        return (
                <div>
                    <ul>
                        <li>
                            <Link to="/">Home2</Link>
                        </li>
                        <li>
                            <Link to="/about">About2</Link>
                        </li>
                        <li>
                            <Link to="/topic">Topics2</Link>
                        </li>
                    </ul>

                    <hr/>
                    {/* 子页面 */}
                    {/* 所有子组件 */}
                    {this.props.children}
                </div>
        )
    }
}

router.js

import React from 'react'
import { HashRouter as Router, Route, Link, Switch, useRouteMatch, useParams } from 'react-router-dom'

import Main from './Main'
import About from './About'
import Topic from './Topic'

import Home from './Home'
import A from './A'
import B from './B'

/**
 * 这个页面就是 最终输出页面
 * 在项目根目录的 index.js 文件里面
 * 
 * import Router from './pages/router_demo/router02/router';
 * ReactDOM.render(<Router />, document.getElementById('root'));
 */
export default class IRouter extends React.Component {

    render() {
        return (
            <>
                <Router>
                    {/* 只能有一个根节点 */}
                    <Home>
                        {/* 页面路由,一个 Route 代表一个页面 */}
                        {/* 4.0  版本开始允许加载多个路由,所以建议加上 exact 进行精准匹配*/}
                        <Route exact={true} path="/" component={Main}/>
                        <Route exact={true} path="/about" component={About}/>
                        <Route exact={true} path="/topic" component={Topic}/>
                        {/* 嵌套路由,不能在父级家 exact,因为先要匹配父级然后才能匹配子集 */}
                        {/* 比如:/nested/a , 会先匹配父级 /nested 饭后才能匹配 /nested/a */}
                        <Route path="/nested" component={() => <Nested />} />
                    </Home>
                </Router>
            </>
        )
    }
}

/**
 * 函数组件
 * @param {*} props 
 */
export function Nested(props) {
    // 获取route的匹配数据
    // path 路径, url 路径, params 参数
    const { path, url, params } = useRouteMatch()
    // 获取 path 参数, http://localhost:3000/a/:number
    // const { number } = useParams()

    console.log(path, url, params)
    return (
        <>
            <ul>
                <li>
                    <Link to={`${path}/a`}>A页面</Link>
                </li>
                <li>
                    <Link to={`${path}/b`}>B页面</Link>
                </li>
            </ul>
            <hr/>
            {/* {props.children} */}
            <Switch>
                <Route exact path={path} component={() => <h3>嵌套路由</h3>}/>
                <Route  path={`${path}/a`} component={A}/>
                <Route  path={`${path}/b`} component={B}/>
            </Switch>
        </>
    )
}

嵌套路由的重点在于,嵌套路由,不能在父级加 exact(精准匹配),因为先要匹配 父级 然后才能匹配 子集
比如:/nested/a , 会先匹配父级 /nested 后才能匹配 /nested/a

<Route path="/nested" component={() => <Nested />} />
.......  分隔符 ...........

// <Nested /> 组件的内部
// 这里的 path 就是 /nested
// `${path}/a` 就是 /nested/a
<Switch>
     <Route exact path={path} component={() => <h3>嵌套路由</h3>}/>
     <Route  path={`${path}/a`} component={A}/>
     <Route  path={`${path}/b`} component={B}/>
</Switch>
上一篇 下一篇

猜你喜欢

热点阅读