• React学习(五)----- React路由


    1、SPA应用的理解

    1、单页Web应用(single page web application,SPA)。

    2、整个应用只有一个完整的页面

    3、点击页面中的链接 不会刷新 页面,只会做页面的 局部更新。

    4、数据都需要通过ajax请求获取, 并在前端异步展现。

    2、路由

    • 什么是路由???
      1.一个路由就是一个映射关系(key:value)
      2.key为路径, value可能是function或component
    • 路由的分类
      • 后端路由
        1)理解: value是function, 用来处理客户端提交的请求。
        2)注册路由: router.get(path, function(req, res))
        3)工作过程:当node接收到一个请求时, 根据请求路径找到匹配的路由, 调用路由中的函数来处理请求, 返回响应数据
      • 前端路由
        1)浏览器端路由,value是component,用于展示页面内容。
        2)注册路由: <Route path="/test" component={Test}>
        3)工作过程:当浏览器的path变为/test时, 当前路由组件就会变为Test组件
    • 路由实现:参考之前写过的文章,地址为:https://www.cnblogs.com/wxh0929/p/15049790.html

    3、react-router-dom

    • 插件的安装:目前安装的版本为5.3.0
      cnpm i react-router-dom -S
    • 路由组件与一般组件的区别
      1、写法不同
           一般组件:<Home />
           路由组件:<Route path="/home" component={Home}></Route>
      2、存放位置不同
           一般组件:components
           路由组件:pages
      3、接收到的props不同
           一般组件:组件标签传递了什么,就能收到什么
           路由组件:接收到三个固定的属性
      1. history:
        1. go: ƒ go(n)
        2. goBack: ƒ goBack()
        3. goForward: ƒ goForward()
        4. push: ƒ push(path, state)
        5. replace: ƒ replace(path, state)
      2. location:
        1. pathname: "/about"
        2. search: ""
        3. state: undefined
      3. match:
        1. params: {}
        2. path: "/about"
        3. url: "/about"
    • 基本路由的使用
      • 效果

      • 示例
        • 导航区的a标签改为Link标签,用于编写路由链接
          {/* 原生html中,靠a标签跳转不同的页面 */}
          {/* <a className="list-group-item" href="./about.html">About</a>
              <a className="list-group-item active" href="./home.html">Home</a> */}
          
          {/* 在React中,靠路由链接实现切换组件 ----- 编写路由链接  Router是指路由器*/}
           <Router>
              <Link className="list-group-item" to="/about">About</Link>
              <Link className="list-group-item" to="/home">Home</Link>
           </Router>
        • 展示区写Route标签进行路径的匹配注册路由
          {/* 注册路由 */}
           <Router>
                <Route path="/about" component={About}></Route>
                <Route path="/home" component={Home}></Route>
           </Router>

          现象:点击导航栏时内容无法更新,这是因为一个应用只能使用一个路由器来管理,解决方法是,在入口文件index.js中使用一个路由器管理App组件

          import React from "react";
          
          import ReactDOM from "react-dom";
          
          import { BrowserRouter as Router } from "react-router-dom";
          
          import App from "./App";
          
          ReactDOM.render(
            <Router>
              <App />
            </Router>,
            document.getElementById("root")
          );
           {/* 在React中,靠路由链接实现切换组件 ----- 编写路由链接*/}
                <Link className="list-group-item" to="/about">About</Link>
                <Link className="list-group-item" to="/home">Home</Link>
          
          {/* 注册路由 */}
                <Route path="/about" component={About}></Route>
                <Route path="/home" component={Home}></Route>
        • 当你的路由链接想动态添加class属性实现高亮的时候,使用NavLink
          {/* NavLink用于被选中的时候添加类名,类名默认为 active */}
          <NavLink className="list-group-item" to="/about">About</NavLink>
          <NavLink className="list-group-item" to="/home">Home</NavLink>
          
           {/* 更改路由选中后的类名,由于使用的是bootstrap的样式,会出现闪烁现象,因此设置样式需给最高权重 */}
          <NavLink activeClassName="side_link" className="list-group-item" to="/about">About</NavLink>
          <NavLink activeClassName="side_link" className="list-group-item" to="/home">Home</NavLink>
          
          {/* 设置路由选中的行间样式 */}
          <NavLink activeStyle={{backgroundColor:'orange'}} className="list-group-item" to="/about">About</NavLink>
          <NavLink activeStyle={{backgroundColor:'orange'}} className="list-group-item" to="/home">Home</NavLink>
          • NavLink的封装
            import React, { Component } from 'react'
            import {NavLink} from 'react-router-dom'
            
            export default class MyNavLink extends Component {
              // 标签体内容是一个特殊的标签属性,通过this.props.children可以获取标签体内容
              render() {
                return (
                  <NavLink activeClassName="side_link" className="list-group-item" {...this.props} />
                )
              }
            }

            例子:

            <MyNavLink to="/about">About</MyNavLink>

      • Switch的使用
        • 通常情况下,path和component是一一对应的关系,但是当一个path匹配多个component时,多个组件都会同时展示,例如
          <Route path="/home" component={About}></Route>
          <Route path="/home" component={Home}></Route>

          现象:

           解决方法:Switch组件包裹你注册的所有路由,那么只会匹配一个路由的组件,不会继续向后匹配(Switch可以提高路由匹配效率,即单一匹配

          <Switch>
              <Route path="/home" component={About}></Route>
              <Route path="/home" component={Home}></Route>
          </Switch>
      • 路由的模糊匹配与严格匹配
        // 默认使用的是模糊匹配,(简单记:【输入的路径to】必须包含要【匹配的路径path】
        // 且【顺序要一致】,如果to="a/home/b" path="/home",则无法匹配,to="/home/a/b" path="/home" ,则可以匹配)
        <MyNavLink to="/home/a/b">Home</MyNavLink>
        <Route path="/home" component={Home}></Route>
        
        // 解决:开启严格匹配,但是严格匹配不要随便开启,需要再开,有些时候开启会导致无法继续匹配二级路由
        <Route exact path="/home" component={Home}></Route>
      • 路由的重定向

                        

    •  嵌套路由(二级路由)的使用
      • 注意:
        1、注册子路由时要写上父路由的path值;
        2、路由的匹配是按照注册路由的顺序进行的;
      • 路由组件传递参数
        • 第一种方式:params(http://localhost:3000/home/message/detail/003/%E6%B6%88%E6%81%AF3)   注意:必须要传,否则进不去
          1、路由链接(携带参数)
          {/* 向路由组件传递params参数 */}
          <Link to={`/home/message/detail/${el.id}/${el.title}`}>{el.title}</Link>
          
          2、注册路由(声明接收)
          <Route path="/home/message/detail/:id/:title" component={Detail}></Route>
          
          3、接收参数
          let { id, title } = this.props.match.params;
        • 第二种方式:search/query(http://localhost:3000/home/message/detail/?id=002&title=%E6%B6%88%E6%81%AF2)注意:不传值也可以进去
          1、路由链接(携带参数)
          {/* 向路由组件传递search参数 */}
          <Link to={`/home/message/detail/?id=${el.id}&title=${el.title}`}>{el.title}</Link>
          
          2、注册路由(search参数无需声明接收,正常注册路由即可)
          <Route path="/home/message/detail" component={Detail}></Route>
          
          3、接收参数
          import qs from 'querystring' //无需安装,react内置
          //备注;获取到的search是urlencoded编码字符串,使用qs进行解析,它的parse方法能解析key=value&key=value的字符串
          let {id,title} = qs.parse(this.props.location.search.slice("1"))
        • 第三种方式:state(http://localhost:3000/home/message/detail)
          1、路由链接(携带参数)
          {/* 向路由组件传递state参数 */}
          <Link to={{pathname:'/home/message/detail',state:{id:el.id,title:el.title}}}>{el.title}</Link>
          
          2、注册路由(state参数无需声明接收,正常注册路由即可)
          <Route path="/home/message/detail" component={Detail}></Route>
          
          3、接收参数
          // 备注:页面刷新后,数据不会丢失,因为BrowserRouter会对history对象进行保存,而location是history的一个参数
          // 而HashRouter刷新后会导致路由state参数的丢失
          let { id, title } = this.props.location.state || {};
    • push与replace模式的区别???
      1、react中的路由跳转默认使用的是push模式,即压栈的形式,会留下痕迹;
      2、replace模式则是替换模式,即类似于无痕浏览;
    • 编程式路由导航:借助this.props.history对象上的API来实现路由的跳转、前进与后退等;
      • 使用场景:点击登录按钮登陆成功后,自动跳转到应用的首页,通过JS代码来实现路由跳转;
      • 跳转方式
        • push跳转
          // 1、携带params参数
          this.props.history.push(`/home/message/detail/${el.id}/${el.title}`)
          
          // 2、携带search参数
          this.props.history.push(`/home/message/detail/?id=${el.id}&title=${el.title}`)
          
          // 3、携带state参数
          this.props.history.push(`/home/message/detail/`,{id:el.id,title:el.title})
        • replace跳转
          // 1、携带params参数
          this.props.history.replace(`/home/message/detail/${el.id}/${el.title}`)
          
          // 2、携带search参数
          this.props.history.replace(`/home/message/detail/?id=${el.id}&title=${el.title}`)
          
          // 3、携带state参数
          this.props.history.replace(`/home/message/detail/`,{id:el.id,title:el.title})
        • go跳转
          // 正数代表前进几步、负数代表后退几步,0代表刷新
          this.props.history.go(2)
        • 前进
          this.props.history.goForward()
        • 后退
          this.props.history.goBack()
        •  如何让一般组件也可以使用编程式路由导航???
          import {withRouter} from 'react-router-dom'
          
          class Header extends React.Component{}
          
          // withRouter可以加工一般组件,让一般组件具备路由组件特有的API,他的返回值是一个新组件
          export default withRouter(Header)

    4、遇到的问题

    • 解决多级路径刷新页面样式丢失的问题
      1、public/index.html中,引入样式 不写 ./  写 / (常用)
      2、public/index.html中,引入样式 不写 ./  写 %PUBLIC_URL%(常用)
      3、使用HashRouter
    北栀女孩儿
  • 相关阅读:
    JS基础语法---函数练习part3---4个练习
    JS基础语法---函数练习part2---10个综合练习(运用:循环/数组/函数)
    JS基础语法---函数练习part1---5个练习
    JS基础语法---函数---介绍、定义、函数参数、返回值
    JS基础语法---冒泡顺序
    JS基础语法---数组案例---9个练习
    JS基础语法---for循环遍历数组
    Python小技巧:使用一行命令把你的电脑变成服务器
    目前最全的Python的就业方向
    这十个Python常用库,学习Python的你必须要知道!
  • 原文地址:https://www.cnblogs.com/wxh0929/p/15238616.html
Copyright © 2020-2023  润新知