react-router路由

安裝

npm i react-router-dom --save
複製代碼

容器組件

  • BrowserRouter 瀏覽器自帶的H5 API, restful 風格,須要配合後臺;
  • HashRouter 使用 hash 方式進行路由,路徑後均有#
  • MemoryRouter 在內存中管理 history ,地址欄不會變化。在 reactNative 中使用。

路由的使用

  1. 跑通路由
//Home.js

import React,{Component}from 'react'
export default class Home extends Component{
    render(){
        return(
        <div>
        Home
        </div>
        )
    }
}

//User.js

import React,{Component}from 'react'
export default class Home extends Component{
    render(){
        return(
        <div>
      User
        </div>
        )
    }
}

//Profile.js

import React,{Component}from 'react'
export default class Home extends Component{
    render(){
        return(
        <div>
        Home
        </div>
        )
    }
}

//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { HashRouter, Router, Route } from 'react-router-dom'

import Home from './components/Home'
import User from './components/User'
import Profile from './components/Profile'


ReactDOM.render(<HashRouter>
  <div>
    <Route path="/home" component={Home} />
    <Route path="/profile" component={Profile} />
    <Route path="/user" component={User} />
  </div>
</HashRouter>, document.getElementById('root'));
複製代碼
  • HashRouter 只能包含一個根元素 所以在全部的Route的外層包了一個div標籤 儘可能放在高的位置 好比主入口的index文件 是一個組件 直接加上<> 就可使用 由於只有在HashRouter下面配置的Route路由纔有用
  • Route 組件有兩個屬性
    • path
    • component 當瀏覽器地址欄中的url和path匹配時會顯示component屬性對應的組件

路由匹配規則

  • 如有一個組件 但願任何路由都顯示時 把path的值設置爲/

Link組件 是 react-router-dom的內置組件 起做用和VueRouter 和 router-link 相似 點擊它能夠跳轉到指定路由

  • 使用時須要導入 能夠爲其設置一個to屬性 值就是單機這個Link時要跳轉到路由的path(link 最後會被渲染成a標籤展現出來)
  • 所以在開發時儘可能少些a 標籤 由於路由不只有 hash 模式仍是 history 模式;寫 Link 它會自動根據模式切換路徑;
  • 且to的值的這個路由path必須在Route 中註冊過才行(只要在應用中註冊過便可)

NavLink 和 Link 的做用同樣,只不過當前導航激活時(NavLink 的 to 和頁面 url 中的路徑相同時導航被激活)會給當前被激活的 NavLink 添加一個 active 類名;若是設置 高亮當前激活的導航 給 active 類名添加樣式就能夠了

二級路由 相似VueRouter 的路由嵌套 直接在須要的地方定義Link 進行路由切換便可

動態路由和路由跳轉

-動態路由的路徑中有一段是不固定的,/user/detail/:id 這最後一段/:id就不是固定的,通常動態路由是用來頁面間傳數據的,動態路由也須要在Route中註冊css

這樣寫的是靜態路由vue

<Route path='/user/detail' component={Home}></Route>   
複製代碼

這樣寫的是動態路由,它與上面這個不是同一個路由,id是必須項react

<Route path='/user/detail/:id' component={Home}></Route>
複製代碼

咱們要跳轉到動態路由的時候,後面的id能夠直接拼接上去webpack

<Link to={`/user/detail/${item.id}`}>
複製代碼

若是咱們須要獲取動態路由後面的動態部分,則使用props.match.params屬性,值是一個對象,動態部分都被放在裏面git

componentWillMount,let { id } = this.props.match.params
複製代碼

編程式導航 用代碼進行路由的切換

全部的被HashRouter等路由渲染的後代組件的props中都有一個路由信息對象history,其中有一個方法push就是用來切換路由的,參數接受一個路由path this.props.history.push('/home') //構造函數constructor中則是第一個參數propsgithub

路由匹配

路由匹配默認的是模糊匹配 開始匹配上了就匹配上了 多個路由匹配則多個component都會被渲染,很明顯這不是咱們想要的,那麼就可使用Route的exact關鍵字讓該路由進行精確匹配,以下web

<Route exact path='/home/list' component={list}></Route>
複製代碼

這樣只有當路由是/home/list的時候纔會渲染這個compoent,路由是/home時並不會渲染npm

render 屬性 值是一個函數 這個函數要求返回一個jsx對象或者組件

當頁面中的url的路徑變化時與Route中的path向匹配時,就會執行這個render函數,而後將其返回的jsx或者組件渲染到頁面上編程

Switch組件 使用時需導入 當Route匹配一個路由後就不在日後匹配 使用該組件

將全部的Route組件放進Switch組件中去,這樣當有一個Route被匹配到後就不會再匹配其餘的Route了json

<Switch>
  <Route path='/' exact render={() => <h1>首頁</h1>}></Route>
  <Route path='/home' component={Home}></Route>
  <Route path='/login' component={Login}></Route>
  <Route component={NotFound}></Route>
</Switch>

複製代碼

設置404 not found頁面

只須要寫一個沒有path的Route就能夠了,

<Route component={NotFound}></Route>
複製代碼

這樣當出現匹配不到的路由就會渲染NotFound組件

create-reat-app建立的項目配置代理

在原來的 create-react-app 腳手架中,是經過 package.json 配置文件來配置代理的。可是,在新版的腳手架中,經過 package.json 只能配置一個代理。若是須要配置多個代理的話,則不能這麼幹了。

  • 新版的代理配置,是經過 /src/setupProxy.js 這個文件來配置的。 在src下面新建文件setupProxy.js
/ 用來配置代理
const proxy = require('http-proxy-middleware')

module.exports = function(app) {
    app.use(
        proxy(
            '/api', {
                target: 'http://localhost:8888',
                changeOrigin: true,
secure: false
            }
        )
    )
}

配置完以後就能夠了,會自動幫咱們引用這個文件

複製代碼

受保護的路由 && 自定義菜單激活樣式

在真實的項目中,咱們會對一些路由進行保護機制,像有些頁面用戶沒有登陸則不容許訪問。vueRouter中有導航守衛來處理這個問題,而在react-router中則須要寫受保護的路由來實現 受保護的路由其實說白了就是咱們本身實現一個組件來包裹Route組件,而後使用咱們本身的組件替換掉Route組件,咱們在咱們本身的組件中作邏輯判斷

import React, { Component } from 'react'
import { Route, Redirect } from  'react-router-dom'

export default ({component: Component, ...others}) => {
  return <Route {...others} render={(props) => {
  // props 是 router 對象,包含了當前路由的信息
    return localStorage.getItem('loginSystem')
      ? <Component {...props} />
      : <Redirect to={{pathname: '/login', from: props.match.url}} />
  }
  }></Route>
}
複製代碼

上面這就是一個受保護的組件,引用以下 import PrivateRoute from './components/Protected'

  • 傳一個path和component給咱們寫的保護組件(其實就是一個函數組件)中去,保護組件是一個函數組件,咱們傳的to以及component都會傳進這個函數組件的第一個參數對象中去,咱們直接將其解構而後給component重命名Component(組件首字母大寫爲了有別於原生標籤),拿到component以及其餘的to等props放進others對象中,而後保護組件返回一個Route組件,將to等props展開放進Route中,而後爲Route設置一個render屬性,render是一個方法,參數是router對象,包含了當前路由的信息,咱們在render中作邏輯判斷用戶是否登陸而後來渲染不一樣的組件(render函數須要返回一個jsx對象或者組件,而後在頁面的url匹配到當前Route的時候被執行,返回的jsx對象或者組件會被渲染)
  • Redirect是react-router-dom上的一個組件,做用是用來進行重定向的,有一個to屬性就是要重定向到的路由path,to的值是一個對象,pathname屬性表示重定向的path地址,其餘屬性會被打成一個location對象傳給重定向後的路由組件的props
  • 若是須要用戶登陸後還跳轉回當前頁面呢?
  • 上面render函數的props路由對象中有咱們當前的路由地址,咱們能夠經過props.match.url獲取到,而後在咱們重定向到登陸頁的時候將咱們獲取到的地址傳過去,而後在用戶登陸成功後在經過編程式導航切回來:this.props.history.push(this.props.location.from) 固然咱們也能夠用受保護組件來實現其餘功能

自定義菜單樣式

咱們寫vue的時候知道在vue中當導航被激活的時候能夠添加router-link-action類樣式來當作激活樣式,那麼在react-router中呢? 仍是使用組件包裝來實現 自定義MenuLink組件

import React, { Component } from 'react'

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

export default ({ to, label }) => {
  return <Route path={to} children={(props) => {
    return <li className={props.match ? 'active' : ''}>
      <Link to={to}>{label}</Link>
    </li>
  }
  }></Route>
}
複製代碼
  • MenuLink組件返回一個Route組件,在Route組件中有一個children屬性,屬性值依舊是一個方法,方法的參數props也是當前路由信息對象,咱們在其中判斷當前路由是否被激活,怎麼判斷?

  • 若是路由被激活則當前路由對象中的match屬性是一個對象,若是沒有被激活這match屬性是null,咱們就經過這個來判斷,若是激活了就爲其添加active類名,沒激活就不添加,active類名就是咱們定義的選中時樣式

  • children 和 render的區別: 雖然值都是一個函數,返回的都是一個jsx對象或者組件 render在頁面的url與當前Route匹配時被調用,將返回jsx對象或者組件渲染 children則是無論頁面你的url和當前Route是否匹配都會被調用,返回的jsx對象或者組件會被渲染

  • 其實套路都是同樣的,就是使用咱們的組件將Route包裹起來,在咱們的組價中作邏輯判斷而後選擇性的返回一個Route組件出來

antd(Ant Design )按需引入以及使用

中文文檔:ant.design/docs/react/…

antd按需引入

  • create-react-app搭建的項目中按需引入antd以及配置Less

  • 使用creat-react-app搭建的項目中的webpack文件是隱藏起來的 暴露wenpack文件的指令是yarn eject. 在使用這個指令以前要先推送一次git文件才行,或者刪除git文件

  • 運行以後會詢問是否暴露,輸入y便可。

  • 此時在項目目錄下會多出一個config文件夾。

  • 按需引入antd:

  • 安裝babel-plugin-import npm i babel-plugin-import -sava

  • 在根目錄下的package.json下的bable中添加相應代碼便可 "babel": { "presets": [ "react-app" ], "plugins": [ [ "import", { "libraryName": "antd", "style": "css" // 引入樣式爲 css // style爲true 則默認引入less } ] ] }

  • 而後就能夠直接使用import { Button } from 'antd'來按需引入的,不須要先引入全局的import 'antd/dist/antd.css'再引入import Button from 'antd/es/button';

  • 配置less creat-react-app搭建的項目中默認沒有爲咱們配置less,若是想用less須要本身配置,也要先使用npm run eject暴露出配置文件來 安裝less: npm i less less-loader -save

  • 在暴露出來的webpack中找到webpack.config.js文件,須要首先在上面的一大堆cosnt常量定義中加入 const lessRegex = /.less/;
const lessModuleRegex = /\.module\.less/; 這是用來識別less的

而後在其module的rules中添加以下代碼: { test: lessRegex, exclude: lessModuleRegex, use: getStyleLoaders( { importLoaders: 2, sourceMap: isEnvProduction && shouldUseSourceMap, }, 'less-loader' ), // Don't consider CSS imports dead code even if the // containing package claims to have no side effects. // Remove this when webpack adds a warning or an error for this. // See github.com/webpack/web… sideEffects: true, }, { test: lessModuleRegex, use: getStyleLoaders( { importLoaders: 2, sourceMap: isEnvProduction && shouldUseSourceMap, modules: true, getLocalIdent: getCSSModuleLocalIdent, }, 'less-loader' ), },

相關文章
相關標籤/搜索