npm i react-router-dom --save
複製代碼
//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'));
複製代碼
-動態路由的路徑中有一段是不固定的,/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
當頁面中的url的路徑變化時與Route中的path向匹配時,就會執行這個render函數,而後將其返回的jsx或者組件渲染到頁面上編程
將全部的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>
複製代碼
只須要寫一個沒有path的Route就能夠了,
<Route component={NotFound}></Route>
複製代碼
這樣當出現匹配不到的路由就會渲染NotFound組件
在原來的 create-react-app 腳手架中,是經過 package.json 配置文件來配置代理的。可是,在新版的腳手架中,經過 package.json 只能配置一個代理。若是須要配置多個代理的話,則不能這麼幹了。
/ 用來配置代理
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'
咱們寫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組件出來
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/; 這是用來識別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' ), },