React路由规则
月光晒了很凉快 人气:01. 路由使用
安装路由模块:
路由模块不是react自带模块,需要安装第3方模块:
yarn add react-router-dom@5
路由相关组件:
路由模式组件:包裹整个应用,一个React应用只需要使用一次
- HashRouter: 使用URL的哈希值实现 (
localhost:3000/#/first
) - BrowserRouter:使用H5的history API实现(
localhost3000/first
)
导航组件:用于指定导航链接, 最终Link会编译成a标签
- Link: 不会有激活样式
- NavLink:如果地址栏中的地址和 to 属性相匹配,则会有激活样式
路由规则定义组件:指定路由规则和对应匹配成功后要渲染的组件
Route:
- path属性:路由路径,在地址栏中访问的地址
- component属性:和规则匹配成功后渲染的组件 /render/children
各组件关系示意图:
定义路由的模式:
为了日后让当前项目中所有的组件都受到路由控制,定义在index.js中,在最顶层定义路由模式。src/index.js
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import './utils/init' // 引入路由相关组件 路由模式组件,告诉当前项目,我们要使用的路由模式 // HashRouter hash路由模式 // BrowserRouter history路由模式,上线时,需要对nginx进行配置 import { BrowserRouter as Router, HashRouter } from 'react-router-dom' ReactDOM.render( <Router> <App /> </Router>, document.getElementById('root') )
定义路由规则:
路由规则组件可以定义在src/index.js
文件中,也可以定义在App组件中。
本次定义在src/App.js
文件中。
import React, { Component } from 'react' // Route 定义路由规则 路由地址和匹配成功后要渲染的组件 import { Route } from 'react-router-dom' // 匹配成功后渲染的组件 import Home from './views/Home' import About from './views/About' class App extends Component { render() { return ( <div> <h3>App组件</h3> <hr /> {/* 定义路由规则 */} <Route path="/home" component={Home} /> <Route path="/about" component={About} /> </div> ) } } export default App
2. 声明式导航
描述:
使用 Link 或 NavLink 组件完成声明式导航的定义、
Link/NavLink 区别:
- Link组件不会根据路由的变化而添加或修改编译后html标签中的属性
- NavLink会根据路由的变化而自动修改编译后html标签中的属性
如果当前的路由规则和 Navlink 中的 To 所写的规则一致则添加 class 样式,
默认名称为 active,可以通过 activeClassName 来修改匹配成功后样式名称。
使用:
import React, { Component } from 'react' // Route 定义路由规则 路由地址和匹配成功后要渲染的组件 // Link 导航组件,它编译生成后的html标签只能是 a // NavLink 导航组件,它编译生成后的html标签只能是 a,但是它有激活样式(地址栏中的地址和to属性匹配,就有内置样式名) import { Route, Link, NavLink } from 'react-router-dom' // 匹配成功后渲染的组件 import Home from './views/Home' import About from './views/About' class App extends Component { render() { return ( <div> <h3>App组件</h3> <div> {/* <Link to="/home">Home</Link> --- <Link to="/about">About</Link> */} {/* NavLink 匹配规则,默认为模糊匹配 严格匹配:exact 修改激活样式名称:activeClassName='aaa' */} {/* <NavLink exact activeClassName='aa' to="/">Home</NavLink> --- */} <NavLink exact to="/">Home</NavLink>--- <NavLink to="/about">About</NavLink> </div> <hr /> {/* 定义路由规则 */} {/* 匹配默认为模糊匹配,而且它还会一直匹配到没有规则组件为止 严格匹配:exact */} <Route exact path="/" component={Home} /> <Route path="/about" component={About} /> </div> ) } } export default App
利用 Switch 严格匹配路由:
import React, { Component } from 'react' // Route 定义路由规则 路由地址和匹配成功后要渲染的组件 // Link 导航组件,它编译生成后的html标签只能是 a // NavLink 导航组件,它编译生成后的html标签只能是 a,但是它有激活样式(地址栏中的地址和to属性匹配,就有内置样式名) // Switch 多个路由规则只匹配一个 import { Route, Link, NavLink, Switch } from 'react-router-dom' // 匹配成功后渲染的组件 import Home from './views/Home' import About from './views/About' class App extends Component { render() { return ( <div> <h3>App组件</h3> <div> {/* <Link to="/home">Home</Link> --- <Link to="/about">About</Link> */} {/* NavLink 匹配规则,默认为模糊匹配 严格匹配:exact 修改激活样式名称:activeClassName='aaa' */} {/* <NavLink exact activeClassName='aa' to="/">Home</NavLink> --- */} <NavLink exact to="/">Home</NavLink>--- <NavLink to="/about">About</NavLink> </div> <hr /> {/* 定义路由规则 */} {/* 匹配默认为模糊匹配,而且它还会一直匹配到没有规则组件为止 严格匹配:exact */} <Switch> <Route path="/about" component={About} /> {/* 注意这个规则要放在最后,否则所有路由都会走 home 页面 */} <Route path="/" component={Home} /> </Switch> </div> ) } } export default App
重定向和404:
import React, { Component } from 'react' // Route 定义路由规则 路由地址和匹配成功后要渲染的组件 // Link 导航组件,它编译生成后的html标签只能是 a // NavLink 导航组件,它编译生成后的html标签只能是 a,但是它有激活样式(地址栏中的地址和to属性匹配,就有内置样式名) // Switch 多个路由规则只匹配一个 // Redirect 重定向 使用它,一定要用到Switch,否则有死循环的问题 import { Route, Link, NavLink, Switch, Redirect } from 'react-router-dom' // 匹配成功后渲染的组件 import Home from './views/Home' import About from './views/About' // import Detail from './views/Detail' import Notfound from './views/Notfound' class App extends Component { render() { return ( <div> <h3>App组件</h3> <div> <NavLink exact to="/">Home</NavLink>--- <NavLink to="/about">About</NavLink> </div> <hr /> <Switch> {/* 如果你想用对于匹配渲染成功后的组件使用编程式导航,你默认情况下,你只能在规则匹配成功后的组件本身中使用,它的子组件都不行 */} <Route path="/home" component={Home} /> <Route path="/about" component={About} /> {/* 重定向 */} <Redirect exact from="/" to="/home" /> {/* 以上的路由没有一个匹配成功的,则用404页面 path属性不要写 */} <Route component={Notfound} /> </Switch> </div> ) } } export default App
3. 编程式导航
App.jsx:
import React, { Component } from 'react' import { Route, Link, NavLink, Switch, Redirect } from 'react-router-dom' // 匹配成功后渲染的组件 import Home from './views/Home' import About from './views/About' // import Detail from './views/Detail' import Notfound from './views/Notfound' class App extends Component { render() { return ( <div> <h3>App组件</h3> <div> <NavLink exact to="/">Home</NavLink>--- <NavLink to="/about">About</NavLink> </div> <hr /> <Switch> {/* 如果你想用对于匹配渲染成功后的组件使用编程式导航,你默认情况下,你只能在规则匹配成功后的组件本身中使用,它的子组件都不行 */} <Route path="/home" component={Home} /> <Route path="/about" component={About} /> {/* 重定向 */} <Redirect exact from="/" to="/home" /> {/* 以上的路由没有一个匹配成功的,则用404页面 path属性不要写 */} <Route component={Notfound} /> </Switch> </div> ) } } export default App
home组件:
import React, { Component } from 'react' import Btn from './Btn' class Home extends Component { jumpUrl = () => { // 写法1 // this.props.history.push('/about') // 写法2 this.props.history.push({ pathname: '/about' }) } render() { return ( <div> <h3>首页展示</h3> <button onClick={this.jumpUrl}>home组件中回关于</button> <Btn {...this.props} /> </div> ) } } export default Home
btn组件:
import React, { Component } from 'react' class Btn extends Component { jumpUrl = () => { this.props.history.push('/about') } render() { return <button onClick={this.jumpUrl}>在btn组件中回关于</button> } } export default Btn
注意:
- 如果你想用对于匹配渲染成功后的组件使用编程式导航,默认情况下,你只能在规则匹配成功后的组件本身中使用,它的子组件都不行
- 直接匹配的路由的子组件要想使用编程式导航,则需要给他传递 props
加载全部内容