React中路由基本&高级使用
一、基本使用
npm install react-router-dom
路由前言:
在原生的html中,靠<a/>跳转不同的页面
在React中靠路由链接实现切换组件
react-router-dom的理解
react-router给web开发人员、native原生开发人员、还有其他开发人员都提供了react-router这个插件
但是web开发人员的化,其实叫做 react-router-dom
(1)它是react的一个插件库(一般react-xxx都是react的一个插件库的)
(2)专门用来实现一个SPA应用(single page 单页面应用),也就是单页面多组件,不像多页面那样每次都要重新刷新页面(页面都抖动,所以要防抖)
路由器是用来管理路由的设备
import React, { Component } from 'react' import {Link, Route} from 'react-router-dom' import Home from './components/Home' import About from './components/About' export default class App extends Component { render() { return ( <div> <div className="row"> <div className="col-xs-offset-2 col-xs-8"> <div className="page-header"><h2>React Router Demo</h2></div> </div> </div> <div className="row"> <div className="col-xs-2 col-xs-offset-2"> <div className="list-group"> <Link className="list-group-item" to="/about">About</Link> <Link className="list-group-item" to="/home">Home</Link> </div> </div> <div className="col-xs-6"> <div className="panel"> <div className="panel-body"> <Route path="/about" component={About}/> <Route path="/home" component={Home}/> </div> </div> </div> </div> </div> ) } }
-
使用react-router-dom插件中的Link来实现路由跳转
-
Link标签中的to属性,用小写的路由
-
-
使用react-router-dom插件中的Route来注册组件
上面的代码会报错:
报错的是Link和Route要用一个Router来包住
但是并不是直接用一个Router标签来把Link和Route直接包住
Router路由器分为两种:BrowserRouter和HashRouter,也就是histroy和hash,所以要引入BrowserRouter或者HashRouter,而不是引入Router,官方报错中没说明白的
之所以要被同一个Router保住,因为这样才是一体的,才能那边改变路由后这边注册对应的路由并切换
但是为了不每次注册组件都要用Router保住,不如 一劳永逸
解决:因为所有的组件上一级都是App.js,而App.js本身也有路由,那么我们就在全部组件和App.js的上一层,也就是index.js文件中的<App/>用Router包裹就行
import React from 'react' import ReactDOM from 'react-dom' import {BrowserRouter} from 'react-router-dom' import App from './App' ReactDOM.render( <BrowserRouter> <App/> </BrowserRouter>, document.getElementById('root') )
Router的分类:
histroy和hash:
hash(描点)路由,在#号后面的都不会作为向服务器请求的路径
二、NavLink的使用
前言:
之所以有了Link还要NavLink,是因为Link不带触发事件(也就是点击触发之后没有样式)
默认activeClassName="active" 如果没写这个属性的话,默认会添加activeClassName="active
<NavLink activeClassName="gogocj" className="list-group-item" to="/about">About</NavLink> <NavLink activeClassName="gogocj" className="list-group-item" to="/home">Home</NavLink>
三、封装NavLink
NavLink是Link的升级版
NavLink默认了active的属性,也可以在标签上定义激活路由的样式
默认activeClassName="active" 如果没写这个属性的话,默认会添加activeClassName="active"
如果使用了bootstrap的话,还要自定义触发样式的话,就要在自定义的后面添加 !important 来添加权限
组件:
import React, { Component } from 'react' import {NavLink} from 'react-router-dom' export default class MyNavLink extends Component { render() { return ( <NavLink activeClassName="gogocj" className="list-group-item" {...this.props} /> ) } }
使用:
<MyNavLink to="/about">About</MyNavLink>
-
其中传递过来的 About,可以在组件中通过this.props.children获取到。而/about,可以通过this.props.to获取到
-
所以传递给MyNavLink组件的包括标签中属性的to,或者是标签体About,都可以通过props获取到,所以传递给NavLink就可以直接用{...this.props} 来获取到
-
所以等价于
<NavLink activeClassName="gogocj" className="list-group-item" to="/about" children="About" />
NavLink中的children属性也是表示标签体内容的
-
四、Switch的使用
为什么要使用:
<Route path="/about" component={About}/> <Route path="/home" component={Home}/> <Route path="/about" component={Test}/>
因为定义了两个path都是/about都是路由,最后的结构是
当路由是/about,About和Test组件都展示出来,但是其实我们并不想要不同组件在同一个路由呈现,是一个很错误的设计模式,所以也是为了性能,比如说:
<Route path="/about" component={About}/> <Route path="/home" component={Home}/> <Route path="/home1" component={Home1}/> <Route path="/home2" component={Home2}/> <Route path="/home3" component={Home3}/> <Route path="/home4" component={Home4}/> <Route path="/home5" component={Home5}/> <Route path="/home6" component={Home6}/> <Route path="/home7" component={Home7}/> <Route path="/home8" component={Home8}/> <Route path="/about" component={Test}/>
这样的话,因为路由是从上到下遍历的,所以要呈现/about的话,要经过很多遍历,特别浪费性能
所以就定义了Switch,只要碰到第一个满足的path就立马停止遍历过程!
实现:直接在注册路由的外面添加一个 Switch标签包裹就行
<Switch> <Route path="/about" component={About}/> <Route path="/home" component={Home}/> </Switch>
五、组件的分类
-
一般组件(就是我们引入之后,直接通过标签进行使用)
-
路由组件(就是我们在Route中注册的,只有path路径等于什么的情况下,才会显示这个组件
路由组件放pages文件夹
一把组件放在components文件夹
路由组件和一般组件的区别:
(1)路由组件会收到 history、location、match重要的路由属性
history:
go: f go(n)
goBack: f goBack()
goForward: f goForward()
push: f push(path, state)
replace: f replace(path, state)
location:
pathname: "/about"
search: ""
state: undefined
match:
param: {}
path: "/about"
url: "/about"
(2)一般组件收到的是父组件传递过来的prop参数