目录
基础路由
结构准备
路由的模糊匹配
嵌套路由
路由传参
声明式路由
路由传递params参数
search(也称query)参数
state传参
编程式路由导航
withRouter
演示
基础路由
单页应用程序 SPA:
整个应用只有一个完整的页面
点击页面中的链接不会刷新页面,只会做页面的局部更新
数据都需要通过ajax请求获取, 并在前端异步展现。
路由:
前端路由:
浏览器端路由,value是component,用于展示页面内容
注册路由: <Route path="/test" component={Test}>
工作过程:当浏览器的path变为/test时, 当前路由组件就会变为Test组件
后端路由:
理解: value是function, 用来处理客户端提交的请求。
注册路由: router.get(path, function(req, res))
工作过程:当node接收到一个请求时, 根据请求路径和方法找到匹配的路由, 调用路由中的函数来处理请求, 返回响应数据
一个路由就是一个映射关系(key:value)key为路径, value可能是function或component
1 明确好界面中的导航区 展示区
2 导航区的a标签改为link标签或者NavLink
<Link to='/组件名'>Demo</Link>
<NavLink to='/组件名'>Demo</NavLink >
3 展示区写Route标签进行路径的匹配
<Router path='/路径名' component={组件名} />
4 <App>最外层包裹一个<BrowerRouter>或<HashRouter>
结构准备
首先安装路由
这里以旧版本演示
npm i react-router-dom@5
准备两个组件
可以看到浏览器地址栏中的路径地址只有最后面的有变换,并且浏览器并没有进行刷新
说明react的路由已经起作用
路由组件与一般组件
1 写法不同:
一般组件: <Demo/>
路由组件: <Route path='/demo' component={Demo}/>
2 存放位置不同:
一般组件: components
路由组件: pages
3 接收到的props不同
一般组件: 写组件标签时传递了什么属性 就能收到什么
路由组件: 接收到三个固定的属性
history,location,match
上面演示的存在一定的问题,就是如果我们有多个需要书写的NavLink标签的话,它们的标签属性大部分一致的情况下,只有to属性不同,这个时候我们其实可以进行自定义封装NavLink来进行优化
封装自定义NavLink
新建自定义组件,包裹NavLink
使用自定义组件时,只传递刚才两个组件不同的部分
测试
可以看到标签体内容是一个特殊的标签属性
通过this,props.children来获取标签体内容
路由的模糊匹配
路由默认开启的是模糊匹配
并且模糊匹配时的路径顺序也是有要求的
可以看到模糊匹配起效果了
路径地址虽然是/foot/hj,但还是定位到了foot组件
下面来查看它的顺序性
foot在后面
foot顺序不在首位进行模糊匹配时没有正确路由出foot组件
此时说明其模糊匹配的规则是模糊匹配后面包含的路径
路由的精准匹配
路由通过标签的 exact属性来控制路由的精准匹配
当标签添加了exact属性(默认为true)时,可以看到模糊匹配已经失效,此时需要精准配置路由路径
Redirect
可以配置页面刚打开加载时重定向到指定的组件
未设置重定向时:
嵌套路由
一般在开发中会有多个组件嵌套,此时再进行路由导航时就需要用到嵌套路由进行路由定义
再在foot组件中定义两个子组件,news,msg,两个组件结构都一致,只有显示内容不一样
定义嵌套路由
注意嵌套路由定义时exact属性最好不要加,不然会由于精准匹配使得嵌套路由失效
路由传参
声明式路由
路由传递params参数
准备一个detail组件,当点击msg组件内的消息体时进行参数传递
打印查看参数
可以看到数据传递到了props的match的params属性中
绑定数据
search(也称query)参数
查看传参位置
发现参数都在props的location的search里
但是参数是 ?id=5&title=戴拿&remark=宇宙该溜子 这种urlencode格式的
这里使用 querystringify库直接进行格式转换
安装 querystringify库
npm i querystringify
引入使用:
state传参
前面两种传参方式都会把参数暴露在地址栏中,这种方式并不是特别安全,路由传参还可以使用state进行传参
可以看到参数都在props.location.state中,并且地址栏中并没有暴露参数
编程式路由导航
借助this.props.history对象上的API对操作路由跳转、前进、后退
路由跳转并留下历史记录:this.props.history.push()
路由跳转但不留下历史记录:this.props.history.replace()
路由后退一条记录:this.props.history.goBack()
路由前进一条记录:this.props.history.goForward()
路由前进或后退任意位置:this.props.history.go()
编程式路由导航传参和前面的三种形式几乎一致
踩坑警告 这里如果使用的是state传参方式的编程式导航的话.主页面js处要使用BrowerRouter包裹
使用HashRouter会使state变为undefined
下面以1分左右gif图展现这个坑
params和search传参和声明式传参一致,这里就不做演示
withRouter
withRouter可以加工一般组件 让一般组件具备路由组件所特有的Api
withRouter的返回值是一个新组件
之前我们都是直接测试的路由组件,所以可以直接使用路由组件持有的api,
如果是一般组件那么该如何让一般组件也能调用路由组件的api从而进行编程式导航呢
演示
准备一个一般组件 low组件
测试:
可以看到low组件中打印props为空对象,根本没有路由组件所有的那些api
这种情况下就可以使用withRouter来对一般组件进行包装
此时就可以让一般组件直接使用路由组件的api了