前言

​ 早期多个页面借助a标签实现路由的跳转,也就是多页面编程,n个导航对应n个html.而且点击链接后,整个页面会刷新,页面会跳转-如果需据会发送请求获取数据。react是单页面多组件应用,链接称为路由链接,点击后,会全局更新,也就是局部刷新,并且不会像发送请求,这里是说这个请求并不是因为你点击链接产生的,组件中的数据还是需要请求的。而点击产生的路径与渲染组件的对应关系取决于react-router插件库了。

SPA
  1. 单页Web应用(single page web application,SPA)。
  2. 整个应用只有一个完整的页面
  3. 点击页面中的链接不会刷新页面,只会做页面的**局部更新。
  4. 数据都需要通过ajax请求获取, 并在前端异步展现。

    1. 路由的理解

    1. 什么是路由?

    1. 一个路由就是一个映射关系(key:value)
    2. key为路径, value可能是function或component

    2. 路由分类

    1. 后端路由:
    • ​ 理解: value是function, 用来处理客户端提交的请求。
    • ​ 注册路由: router.get(path, function(req, res))
    /*
      请求地址: http://localhost:3000/search/users?q=aa
      后台路由
        key: /search/users
        value: function () {}
    */
    app.get("/search/users", function (req, res) {
      const {q} = req.query
      axios({
        url: 'https://api.github.com/search/users',
        params: {q}
      }).then(response => {
        res.json(response.data)
      })
    })
    • ​ 工作过程:当node接收到一个请求时, 根据请求路径找到匹配的路由, 调用路由中的函数来处理请求, 返回响应数据
    1. 前端路由:浏览器端路由
    • 理解: value是component,用于展示页面内容
    • 注册路由:

       <Route path="/test" component={Test}>
    • 工作过程:当浏览器的path变为/test时(路由链接可以直接修改浏览器地址), 当前路由组件就会变为Test组件
3. 路由工作原理

image-20211204110116404

这是典型的多页面应用,点击导航区切换,请求另一个页面,展示区是变了。会跳转到另一个页面,并且会刷新,多个展示区需要多个html。

原理:
  1. 一开始的地址栏是没有参数的,127.0.0.1/ ,没有多页面应用的xxx.html的后缀(.html 代表一个页面o)
  2. 点击路由链接后,路由会修改浏览器的地址,127.0.0.1/ home/ 页面并不会发生跳转。【区别于a链接 点击后不跳转】
  3. 路由中检测浏览器的路径(参数)变化(这里是会忽略前面的ip 以及port)匹配组件参数,展示相应的组件
    路由监测的实现: 得益于history对象 浏览器历史记录

​ 点击导航区,路径改变 === 路径改变,被检测 === 匹配组件,展示区变化。

  1. 为什么点击路由链接后地址栏会变路径呢?谁监测路径的变化呢?

    依靠浏览器的历史记录 history对象

​ 我们一般不会直接去操作这个window.history 去操作浏览器的路径 历史记录的修改以及替换 因为原生的api不好用 so
借助一个库history.js 这个创建的history对象本质也是操作了bom的history
history.push/forward/go/back/replace

两种路由模式: history: hash(# 兼容性好) browser

2. react-router-dom的理解

  • react-router 插件库其实有三种实现 适用于三种平台 web(dom) native(原生) anywhere(通用性强 api 过多)
  • react的一个插件库。本质是react写的,依赖于react才可以工作。
  • 专门用来实现一个SPA应用
  • 基于react的项目基本都会用到此库。

router: 路由器 管理路由
route: 路由(接口 天线)

原生写react

1.复杂需要多个html 引入各种react文件 编码慢
2.通过js修改为jsx的形式依靠浏览器babel 翻译 代码过多浏览器忙不过来
3. 使用cli 简单快速搭建react 应用  cli是webpeck 搭建的,他有好多loader plugins 由很多功能‘
4.安装脚手架 create-react-app库帮助你安装cli
5.创建项目 create-react-app 项目名
6.启动 npm start
webpeck 官方把关于react的配置文件隐藏了 执行eject 会暴露处所有的配置文件并且回不去了
7.react中不建议使用jquery 因为他注重的是操作原生dom。而 react是不关注视图层的
axios: 轻量 可运行在服务端 支持promise 本质就是xmlHttpRequest对象的封装

3. react-router-dom相关API

3.1. 内置组件
  1. <BrowserRouter>

    路由器 管理路由 一个应用只有一个路由器。

       <BrowserRouter>
          <App/>
       </BrowserRouter>

    <HashRouter>

  2. 路由器 管理路由。
  3. <Route>

    作用:注册路由 匹配组件 path 路径 components 组件

    <Route path="/about" component={About}/>

  4. <Redirect>

            1.一般写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由
            2.具体编码:
                    <Switch>
                        <Route path="/about" component={About}/>
                        <Route path="/home" component={Home}/>
                        <Redirect to="/about"/>
                    </Switch>
                    
                    Redirect是值得匹配不到后,显示的组件,就是最后承担者,兜底的人。
    
  5. <Link>

      路由链接link 本质是a标签 作用就是点击后修改地址栏路径 浏览器的历史记录就会工作 当路径变化就会匹配组件 
     <a href="./home.html">Home</a> ===>  <Link to="/home">Home</Link>
    使用方式与a链接一样,只是href的值是具体的网页地址,to的属性值是路径参数(没有点)
    Link需要被路由器所管理,这个路由器需要具体,hash / browser,link 可以实现浏览器的路径变化以及历史记录的添加
  6. <NavLink>

     点击时路由链接高亮的效果,点击时给链接动态的追加一个类class=active 由于boot里面active恰好是高亮 可设置 activeClassName 属性 制定选中后的类名
      注意boot里面样式权重大,因为boot默认会给点击的添加active类,导致你有两个类。??可是为什么闪烁你写的需要important

    组件标签体就是标签的children属性 值可通过this.prop.children获取

  7. <Switch>

           <MyNavLink to="/about">About</MyNavLink>
           <MyNavLink to="/home">Home</MyNavLink>
            /* 制定浏览器路径以及浏览器的历史记录 */
           <Route path="/about" component={About}/>
           <Route path="/home" component={Home}/>
           <Route path="/home" component={Test}/>
           /* 匹配路径 显示组件 会发现都展示了  如果注册的路由特别多,他会一直匹配,只要满足就显示,效率低下 */
    1.  通常情况下,path和component是一一对应的关系。
    2.  Switch可以提高路由匹配效率(单一匹配) 匹配一个后不会继续匹配了。
    
3.2. 其它
  1. history对象
  2. match对象
  3. withRouter函数

4. 路由使用

​ 1.明确好界面中的导航区、展示区
​ 2.导航区的a标签改为Link标签

    <Link to="/xxxxx">Demo</Link>

​ 3.展示区写Route标签进行路径的匹配

    <Route path='/xxxx' component={Demo}/>

​ 4.<App>的最外侧包裹了一个<BrowserRouter>或<HashRouter>

4.1 路由组件与一般组件
    1.写法不同:
          一般组件:<Demo/>
          路由组件:<Route path="/demo" component={Demo}/>
    2.存放位置不同:
         一般组件:components
          路由组件:pages
    3.接收到的props不同:
        一般组件:写组件标签时传递了什么,就能收到什么
        路由组件:接收到三个固定的属性
        history:
            go: ƒ go(n)
            goBack: ƒ goBack()
            goForward: ƒ goForward()
            listen:f listen(listenr)
            push: ƒ push(path, state)
            replace: ƒ replace(path, state)
            location: history.location === location
        location:
            pathname: "/about"
            search: ""
            state: undefined
        match:
            isExact: true 是否精准匹配
            params: {}
            path: "/about"
            url: "/about"
4.2 样式丢失
        1.public/index.html 中 引入样式时不写 ./ 写 / (常用)
        2.public/index.html 中 引入样式时不写 ./ 写 %PUBLIC_URL% (常用)
        3.使用HashRouter
4.3 路由的严格匹配与模糊匹配
                                <MyNavLink to="/home/a/b">Home</MyNavLink>
                                <Route path="/home" component={Home}/>
                                拿出 home a b 与home可以匹配 给的多是可以的
        1.默认使用的是模糊匹配(简单记:【输入的路径】必须包含要【匹配的路径】,且顺序要一致)
        2.开启严格匹配:<Route exact={true} path="/about" component={About}/>
        3.严格匹配不要随便开启,需要再开,有些时候开启会导致无法继续匹配二级路由
4.4 开启repalce模式
    <Link repalce to="/xxxxx">Demo</Link>  替换模式
4.5 withRouter
export default withRouter(Header)
Header组件的props里就有history了
withRouter可以加工一般组件,让一般组件具备路由组件所特有的API
withRouter的返回值是一个新组件

5. 嵌套路由使用

    1.注册子路由时要写上父路由的path值
    2.路由的匹配是按照注册路由的顺序进行的

6. 向路由组件传递参数数据

        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
                    备注:刷新也可以保留住参数

7. 多种路由跳转方式

    借助this.prosp.history对象上的API对操作路由跳转、前进、后退
        -this.prosp.history.push()
        -this.prosp.history.replace()
        -this.prosp.history.goBack()
        -this.prosp.history.goForward()
        -this.prosp.history.go()
8. 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可以用于解决一些路径错误相关的问题。

小懵
4 声望0 粉丝

下一篇 »
redux

引用和评论

推荐阅读
0 条评论