SPA 单页面应用APP: 更改地址栏信息更改组件
1、history库的使用
知识点1:地址栏的历史记录是栈的形式,每一次页面的跳转都会压入一条历史记录
history 的基本使用
<body>
<a href="http://www.atguigu.com" onclick="return push('/test1') ">push test1</a><br><br>
<button onClick="push('/test2')">push test2</button><br><br>
<button onClick="replace('/test3')">replace test3</button><br><br>
<button onClick="back()"><= 回退</button>
<button onClick="forword()">前进 =></button>
<script type="text/javascript" src="https://cdn.bootcss.com/history/4.7.2/history.js"></script>
<script type="text/javascript">
<!-- 方法一,直接使用H5推出的history身上的API let history = History.createBrowserHistory() -->
<!-- 方法二,hash值(锚点)-->
let history = History.createHashHistory()
<!--向栈里面添加一条记录-->
function push (path) {
history.push(path)
return false
}
<!--替代最新的一条历史记录-->
function replace (path) {
history.replace(path)
}
<!--反回上一条记录-->
function back() {
history.goBack()
}
<!--返回吓一条记录-->
function forword() {
history.goForward()
}
<!--添加路径的监听-->
history.listen((location) => {
console.log('请求路由路径变化了', location)
})
</script>
</body>
2、react官方的库 yarn add react-router-dom
内置库的引入: import {Route,NavLink} from react-router-dom
注释:Route,NavLink 是 react-router-dom 封装的组件所以首字母大写。
1. 编写路由(App组建中使用):
编写路由对应的 DOM 是页面上的 导航栏
原生html中,靠跳转不同的页面
<a className="list-group-item" href="./about.html">About</a>
<a className="list-group-item active" href="./home.html">Home</a>
在React中靠路由链接实现切换组件–编写路由链接
注:Link ===》 NavLInk 是因为 Navlink 标签在使用 bootstraps 时获去焦点是会自动添加一个 active 的类名。可以喂焦点DOM添加样式
<NavLink activeClassName="atguigu" className="list-group-item" to="/about">About</NavLink>
<NavLink activeClassName="atguigu" className="list-group-item" to="/home">Home</NavLink>
2. 注册路由(App组建中使用):
注册路由对应的 DOM 是页面上的展示栏
<Route path="/about" component={About}/>
<Route path="/home" component={Home}/>
3. 小知识点:
a、在入口文件中需要包含路由组件的一般组件包裹一层 <包含路由组件的一般组件 />
想要使用注册、编写路由组件必须在所有的路由组件的注册、编写包裹在同一个 标签里面
import {BrowserRouter} from 'react-router-dom'
//引入App
import App from './App'
ReactDOM.render(
<BrowserRouter>
<App/>
</BrowserRouter>,
document.getElementById('root')
)
b、路由组件放在和src下的 pages 文件夹中
一般组件放在 components 文件夹中
c、路由组建中那怕不传数据他的 pros 中还是能接受到数据
history || location || match
一般组件不传递数据他的 peops 是接受不到数据的
4. MyNavLink 的封装
MyNavLink 的使用 (App组建中使用)
<!--在React中靠路由链接实现切换组件--编写路由链接-->
<MyNavLink to="/about" a=1 b=2 c=3 >About</MyNavLink>
<MyNavLink to="/home" a=22 b=33 c=44 >Home</MyNavLink>
MyNavLink 的封装
import React, { Component } from 'react'
import {NavLink} from 'react-router-dom'
export default class MyNavLink extends Component {
render() {
return (
<NavLink activeClassName="atguigu" className="list-group-item" {...this.props}/>
<!--吧路由组件独有的属性传递过来渲染到 NAVLink 组件中,-->
<!--标签体内容通过 childen=标签体内容 传递进来-->
)
}
}
注释:路由组件相同的类属行可以放在 MyNavLink 组件中,使用编写路由组件的时候只需要传递过来去独有的类名和数据
About 路由组件的 this.props ======> { to="/about",a=1,b=2,c=3,childen="About" }
Home 路由组件的 this.props ======> { to="/home",a=22,b=33,c=44,childen="Home" }
< MyNavLink to="/about" > About < /MyNavLink > 其中的 About 标签体 是一个标签属性: childen=“About”
在传递属性的时候可以直接写在 MyNavLink 标签内通过 pros 传递到 MyNavLink 组件中,对 NavLink 组件进行封装。
<!--使用路由组件的组件-->
<MyNavLink to="/home/message">Message</MyNavLink>
<!--NavLink 组件中对 NavLink 组件进行封装-->
<NavLink activeClassName="atguigu" className="list-group-item" {...this.props}/>
5、swith 的使用
注释:找到第一个符合条件的路由组件后就不再继续往下继续查找路由组建
{/* 注册路由 */}
<Switch>
<Route path="/about" component={About}/>
<Route path="/home" component={Home}/>
<Route path="/home" component={Test}/>
</Switch>
//地址栏访问 /about 或者 /home 时:
//注册路由只会渲染初 About 和 Home 路由组件 Test 路由组建不会呗查找到
//如果不加上 switch 标签就 Test 路由组件也会被渲染到页面上
6. bootstraps 的样式错误
解决方法
-
引入 bootstraps.css 时,把 ./css/… ====> /css/…
-
引入 bootstraps.css 时,把 ./css/… ====> %PUBLIC_URL%/css/…
-
在入口文件中,不使用 BrowserRouter 标签包裹包含路由组件的组件 ====> HashRouter 标签包裹该组件
7.精准匹配 和 模糊匹配
注册路由的 path = “/home” ====== > 编写路由中给出 to = “/home/a/b” 就能匹配上 可以渲染组件
注册路由的 path = “/home/a/b/c” ====== > 编写路由中给出 to = “/home” 则不能匹配上 无法渲染组件
编写路由(导航栏)中 【输入的路径】 包含注册路由(展示栏)中 【匹配的路径】 且 顺序一致 就能匹配上
注册路由时添加 exact={true} 或者 exact 开启严格模式则必须编写路由时和注册路由时的路径完全一样才能匹配的上。
严格匹配不能随便开启,需要的时候在开启,有些时候会导致无法继续匹配二级路由