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' ), },