react-router深入浅出

1.改变页面路由的两种方式

监听hash的改变

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div class="app">
        <a href="#/home">首页</a>
        <a href="#/about">关于</a>


        <div class="router-view"></div>
    </div>


    <script>
        // 监听router-view DOM
        const oDiv = document.getElementsByClassName('router-view')[0];

        //监听URL的改变
        window.addEventListener('hashchange', () => {
    
    
            // console.log('hashchange', location.hash);
            switch(location.hash) {
    
    
                case "#/home":
                    oDiv.innerHTML = '首页';
                    break;
                case "#/about":
                    oDiv.innerHTML = "关于";
                    break;
                default:
                    oDiv.innerHTML = ""; 
            }
        })
    </script>
</body>
</html>

hash的缺点: 路径里面有一个 “#”,看起来不像真实路径地址。

HTML5 history

在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div class="app">
        <a href="/home">首页</a>
        <a href="/about">关于</a>


        <div class="router-view"></div>
    </div>


    <script>
    const oDiv = document.getElementsByClassName('router-view')[0];

    //取消a元素的默认行为
    const aList = document.getElementsByTagName('a');
    
    Array.from(aList).forEach( el => {
    
    
        el.addEventListener('click', e => {
    
    
            e.preventDefault();
            // console.log('取消了a元素默认行为');
            const href = el.getAttribute('href');
            history.pushState({
    
    },'',href)
            urlChange()
        } )
    } )


     function urlChange() {
    
    
            switch(location.pathname) {
    
    
                case "/home":
                    oDiv.innerHTML = '首页';
                    break;
                case "/about":
                    oDiv.innerHTML = "关于";
                    break;
                default:
                    oDiv.innerHTML = ""; 
            }
        }

        

        // 执行返回操作的时候,路径变了,但是下面的内容没有变化
        window.addEventListener('popstate',() => {
    
    
            // console.log('popstate')
            urlChange();
        })
    </script>
</body>
</html>

2.react-router

在这里插入图片描述

3.react-router 主要的api

在这里插入图片描述

4.react-router 基本使用

import React, {
    
     PureComponent } from 'react'

import {
    
    
    BrowserRouter,
    Link,
    Route
} from 'react-router-dom'

import Home from './pages/home'
import About from './pages/about'
import Profile from './pages/profile'

export default class App extends PureComponent {
    
    
    render() {
    
    
        return (
            <div>
                <BrowserRouter>
                    <Link to="/">首页</Link>
                    <Link to="/about">关于</Link>
                    <Link to="/profile">我的</Link>



                <Route exact path="/" component={
    
    Home}/>
                <Route path="/about" component={
    
    About}/>
                <Route path="/profile" component={
    
    Profile}/>
                </BrowserRouter>
            </div>
        )
    }
}

 <Route exact path="/" component={
    
    Home}/>

因为路径使用的是模糊匹配,所以加入exact可以实现精准匹配路由,不会出现渲染出我们不想要的页面。

5.react-router 深入解析

link都会渲染出来:并且都会显示为a标签

route不一定会显示,当页面的路由与route中的path想匹配的时候才会显示该路由下的页面。toute的位置我们可以自行决定。

navLink的使用

选中哪一个路径,就将对应的路径变为红色。

 <NavLink exact to="/" activeStyle={
    
    {
    
    color:"red"}}>首页</NavLink>
 <NavLink to="/about" activeStyle={
    
    {
    
    color:"red"}}>关于</NavLink>
 <NavLink to="/profile" activeStyle={
    
    {
    
    color:"red"}}>我的</NavLink>

在这里插入图片描述

react-router switch的使用

当我们匹配某一个路径的时候,我们会发现一些问题。
比如: /about路径被匹配到的时候,最后一个组件noMatch也被匹配到了
但是我们在开发中有一种排他思想,只要匹配到了第一个组件,那么后面的组件就不想继续匹配了。这个时候,
我们就需要使用Switch来将所有的Route进行包裹就可以了。

  • 代码示例
<BrowserRouter>
                    <NavLink exact to="/" activeStyle={
    
    {
    
    color:"red"}}>首页</NavLink>
                    <NavLink to="/about" activeStyle={
    
    {
    
    color:"red"}}>关于</NavLink>
                    <NavLink to="/profile" activeStyle={
    
    {
    
    color:"red"}}>我的</NavLink>


                <Switch>
                <Route exact path="/" component={
    
    Home}/>
                <Route path="/about" component={
    
    About}/>
                <Route path="/profile" component={
    
    Profile}/>
                <Route component={
    
    noMatch}/>
                </Switch>
                </BrowserRouter>

react-router redirect的使用

当我们页面想要发生重定向的时候,就需要使用到redirect
这个操作经常会在我们登录页面也是用,当用户登录状态为true时,显示user页面,为false的时候,显示login页面。

代码示例:

export default class user extends PureComponent {
    
    

    constructor(props){
    
    
        super(props)

        this.state = {
    
    
            isLogin:true
        }
    }

    render() {
    
    
        return  this.state.isLogin ? (
            <div>
                <h2>user</h2>
                <h2>用户名: kangjiahao</h2>
            </div>
        ) : <Redirect to="/login"/>
    }
}

react-router 路由嵌套(二级,三级路由)

我们在开发中比较常见的一个路由的应用就是路由嵌套。
about下的路由就去about组件内部实现。 包括 以及

举个例子:
在这里插入图片描述
在这里插入图片描述

代码实现;

import React, {
    
     PureComponent } from 'react'
import {
    
     NavLink, Route, Switch } from 'react-router-dom'

function AboutHistory(props){
    
    
    return <h2>企业成立于2000年,拥有悠久的历史。</h2>
}

function AboutCulture(props){
    
    
    return <h2>创新 || 发展  || 共赢</h2>
}

function AboutUs(props){
    
    
    return <h2>联系电话: 8888-9999-0000</h2>
}


export default class About extends PureComponent {
    
    
    render() {
    
    
        return (
            <div>
                <NavLink exact to="/about" activeStyle={
    
    {
    
    color:"gold",fontSize:'25px'}}>企业历史</NavLink>
                <NavLink exact to="/about/history" activeStyle={
    
    {
    
    color:"gold",fontSize:'25px'}}>企业文化</NavLink>
                <NavLink exact to="/about/us" activeStyle={
    
    {
    
    color:"gold",fontSize:'25px'}}>联系我们</NavLink>




                <Switch>
                    <Route exact path="/about" component={
    
    AboutHistory}/>
                    <Route exact path="/about/history" component={
    
    AboutCulture}/>
                    <Route exact path="/about/us" component={
    
    AboutUs}/>
                </Switch>
            </div>
        )
    }
}

手动跳转路由

<button onClick={
    
     e => this.jumpToJion()}>加入我们</button>



jumpToJion(){
    
    
        this.props.history.push('/about/jion');
    }

react-router 参数传递

一般传递参数有三种方式:
第一种:动态路由传递参数

第二种:search方法传递(不建议使用)

传值:  <NavLink to="/details?data=kangjiahao" activeStyle={
    
    {
    
    color:"red"}}>详情</NavLink>

获取值: console.log(this.props.location.search)

第三种:采用to 的方式 传入一个对象来实现传值(建议使用)

 传值:
 <NavLink to={
    
    {
    
    
                    pathname:"/details",
                    search:"?name=abc",
                    state: this.state.data
              }} 
              activeStyle={
    
    {
    
    color:"red"}}>详情</NavLink>


取值:
const location = this.props.location;
   、console.log(location)

react-router 路由映射单独文件夹配置

安装单独的包:react-router-config

新建文件夹 -> router -> index.js

import Home from '../pages/home'
import About from '../pages/about'
import Profile from '../pages/profile'
import User from '../pages/user'
const routers = [
    {
    
    
        path:'/',
        exact:true,
        component: Home
    },
    {
    
    
        path:'/about',
        component: About
    },
    {
    
    
        path:'/profile',
        component: Profile
    },
    {
    
    
        path:'/user',
        component: User
    }
]

export default routers;

二级路由写法:

二级路由写法代码示例:

import Home from '../pages/home'
import About,{
    
    AboutHistory, AboutCulture, AboutUs, JionUs} from '../pages/about'



import Profile from '../pages/profile'
import User from '../pages/user'
const routers = [
    {
    
    
        path:'/',
        exact:true,
        component: Home
    },
    {
    
    
        path:'/about',
        component: About,
        routes:[
            {
    
    
                path:'/about',
                exact:true,
                component:AboutHistory
            },
            {
    
    
                path:'/about/history',
                component:AboutCulture
            },
            {
    
    
                path:'/about/us',
                component:AboutUs
            },
            {
    
    
                path:'/about/jion',
                component:JionUs
            }
        ]
    },
    {
    
    
        path:'/profile',
        component: Profile
    },
    {
    
    
        path:'/user',
        component: User
    }
]

export default routers;

如何拿到封装好的路由里面的子路由:

this,props。route()  就可以拿到对应的子路由 

使用二级路由:

引入函数renderRoutes
import {
    
     renderRoutes } from 'react-router-config'


使用函数嵌套传递过来的route。即可
  {
    
         
  		renderRoutes(this.props.route.routes)
  }



{
    
    /* <Switch>
                    <Route exact path="/about" component={AboutHistory}/>
                    <Route exact path="/about/history" component={AboutCulture}/>
                    <Route exact path="/about/us" component={AboutUs}/>
                    <Route exact path="/about/jion" component={JionUs}/>
                </Switch> */}

             

猜你喜欢

转载自blog.csdn.net/qq_43955202/article/details/108563068