1. 路由的理解
什么是路由?
- 一个路由就是一个映射关系(key:value)
- key为路径, value可能是function或component
2. 路由分类
后端路由:
- 理解: value是function, 用来处理客户端提交的请求。
- 注册路由: router.get(path, function(req, res))
- 工作过程:当node接收到一个请求时, 根据请求路径找到匹配的路由,
调用路由中的函数来处理请求, 返回响应数据
前端路由:
- 浏览器端路由,value是component,用于展示页面内容。
- 注册路由: <Route path="/test"component={Test}>
- 工作过程:当浏览器的path变为/test时, 当前路由组件就会变为Test组件
3. react-router-dom相关API
// npm install --save react-router-dom 下载react-router-dom包
1. <BrowserRouter>
以下组件必须在BrowserRouter/HashRouter包裹中,
才能正常使用Link和Route
2. <HashRouter>
#后面的属于hash值(锚点值) 后面的内容不会作为资源发送给服务器
3. <Route path='/xxxx' component={路由组件}/>
4. <Redirect>
5. <Link to="/xxxxx">Demo</Link> 跳转路由
6. <NavLink activeClassName="xxxx"> 路由高亮指定class名,默认为active
7. <Switch> 可以提高路由匹配效率(单一匹配)
8. whitRouter() 可以加工一个一般组件,拥有路由组件特有的api,返回值是一个新的组件 export default whitRouter(一般组件名)
4.路由组件的props参数
// 1.路由组件接收的props为 history、match、location三个对象包含了当前路由的相关信息
// 2.props会默认接收children属性 用来存放标签体的内容
路由组件:接收到三个固定的属性
history:
go: ƒ go(n)
goBack: ƒ goBack()
goForward: ƒ goForward()
push: ƒ push(path, state)
replace: ƒ replace(path, state)
location:
pathname: "/about"
search: ""
state: undefined
match:
params: {}
path: "/about"
url: "/about"
5.路由的严格匹配与模糊匹配
1. 默认使用的是模糊匹配(简单记:【输入的路径】必须包含要【匹配的路径】,且顺序要一致)
2.开启严格匹配:<Route exact={true} path="/about" component={About}/>
3.严格匹配不要随便开启,需要再开,有些时候开启会导致无法继续匹配二级路由
6. Redirect的使用
1.一般写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由
2.具体编码:
<Switch>
<Route path="/about" component={About}/>
<Route path="/home" component={Home}/>
<Redirect to="/about"/>
</Switch>
7. 嵌套路由及跳转传参
1.注册子路由时要写上父路由的path值
2.路由的匹配是按照注册路由的顺序进行的
1.params参数
路由链接(携带参数):<Link to='/demo/test/tom/18'}>详情</Link>
注册路由(声明接收):<Route path="/demo/test/:name/:age" component={Test}/>
接收参数:this.props.match.params
2.search参数
路由链接(携带参数):<Link to='/demo/test?name=tom&age=18'}>详情</Link>
注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
接收参数:this.props.location.search
备注:获取到的search是urlencoded编码字符串,需要借助querystring解析
3.state参数
路由链接(携带参数):<Link to={{pathname:'/demo/test',state:{name:'tom',age:18}}}>详情</Link>
注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
接收参数:this.props.location.state
备注:刷新也可以保留住参数
借助this.prosp.history对象上的API对操作路由跳转、前进、后退
-this.prosp.history.push()
-this.prosp.history.replace()
-this.prosp.history.goBack()
-this.prosp.history.goForward()
-this.prosp.history.go()
7.BrowserRouter与HashRouter的区别
1.底层原理不一样:
BrowserRouter使用的是H5的history API,不兼容IE9及以下版本。
HashRouter使用的是URL的哈希值。
2.path表现形式不一样
BrowserRouter的路径中没有#,例如:localhost:3000/demo/test
HashRouter的路径包含#,例如:localhost:3000/#/demo/test
3.刷新后对路由state参数的影响
(1).BrowserRouter没有任何影响,因为state保存在history对象中。
(2).HashRouter刷新后会导致路由state参数的丢失!!!
4.备注:HashRouter可以用于解决一些路径错误相关的问题。
理解须知:
- webpack通过devServer开启的本地服务localhost:3000代表脚手架
- public文件夹相当于localhost:3000内置服务器的根路径
- localhost:3000/css/bootsrap.css <=> src=" /css/bootsrap.css"
问题:
使用src="./css/bootsrap.css"的相对路径的方式引入,多级路径且页面刷新样式则丢失
原因:
因为路径错误(localhost:3000/atguigu/home/css/bootsrap.css)请求了一个不存在的资源,则返回public文件夹下的index.html(兜底)
解决:
1.public/index.html 中 引入样式时不写 ./ 写 / (常用)
2.public/index.html 中 引入样式时不写 ./ 写 %PUBLIC_URL% (常用)
3.使用HashRouter
#后面的被认为是前端的资源不会带给服务器,发请求时会忽略#后面的内容(hash值)(/atguigu/home)