单页面应用程序

448 阅读5分钟
  • 利用哈希值,哈希值变了并不会导致页面重新刷新,react会监听到哈希值改变了,就会把对应的组件给渲染出来,别的组件销毁掉。哈希值自己设置。
  • 路由简单来说就是两端连接的路径,找到最短的路径进行连接。

单页面web应用(singie page web application)

  1. 整个应用一个完整的页面。
  2. 点击页面的连接不会刷新页面,只会做页面的局部更新。
  3. 数据都需要通过aja请求获取,并在前端异步展现。

理解路由

多页面网站是通过超链接来实现页面的切换的,所有的每次点击超链接时浏览器都需要刷新请求新的页面,而单页面应用程序主要通过路由来实现内容的切换,在react当中也就是切换组件。

那如何实现组件的切换呢?

react路由是通过一种特殊的链接,点击时会修改浏览器地址栏中的地址,但是浏览器是会忽略掉这次变化所有切面不会被跳转,但是在路由会监听到地址(path)的变化从而根据不同的地址渲染出来不同的组件(component/element)

安装

RR5本次采用单代码仓库模型架构(monorepo),这意味着这个仓库里面有若干相互独立的包,分别是:

  • react-router React Router核心包
  • react-router-dom 用于DOM绑定的React Router 适用于网页的
  • react-router-native 用于React Native的React Router 适用于native程序的
  • react-router-redux React Router和Redux的集成 适用于所有场景的
  • react-router-confing 静态路由配置的小助手

react-router v6

重命名为

  • <Route>的新特性变更。Route中统一使用element属性,去掉原来的component和render,使用index设置默认路由组件。
  • 嵌套路由变得更简单,子路由可以省略上级路由,比如/page1/page1-1以往需要写完成的path,而目前可以集成商及页面的路由了,甚至斜线都可以省略;
  • 用useNavigate代替useHistory
  • 新增了Outlet,相当于{this.props.children}
  • 大小减少:从20kb到8kb

6.4.0版本的路由 下载依赖:npm i react-router-dom -D

react-router-dom中的基础组件主要分为三类

  1. 路由器组件 <Router>
  2. 路由匹配组件 <Route>
  3. 导航组件 <Link>

<Router>路由器组件

如果我们希望页面某个本部分的内容需要根据URL来动态显示,需要用到Router组件,该组件是一个容器组件,只需要用它包裹URL对应的根组件即可。

  • <Router>就是路由器组件名,它是路由实现最主要的一个组件,而是用它衍生出来的几个;Router是所有路由组件共同的底层接口,一般我们的应用并不会使用这个接口,而是使用高级的路由:

  • <BrowserRouter>:它实际监听的是浏览器历史记录的变化,修改的还是浏览器的地址栏的地址。使用HTML5提供的history API来保持UI和URL的同步。会把历史记录存到历史记录对象里。

  • <HashRouter>:使用URL的hash(例如:window.loaction.hash)来保持UI和URL的同步

  • <MemoryRouter>:能在内存保存你的“URL”的历史记录(并exact没有对地址栏读写)

  • <StaticRouter>:从不会改变地址。(用它实现不了切换) 我们经常使用的是前两个(把上面的背下来)

<Route>路由匹配组件

  • 组件,加上这个组件,匹配上一个以后,就不再往后去找了。这个组件是必须写的,但Switch在6里面改成了叫Routes,所以要引入:import {Routes,HashRouter} from "react-router-dom"。
Route组件主要的通就是当一个location匹配路由的path时,渲染某些UI。

地址栏的地址改变了,到底显示哪个组件,由<Route>来控制

<Route>组件有如下属性:

  1. path(string):路由匹配路径(没有path属性的Route总是会匹配,自己设置的哈希值)
  2. component:设置显示哪个组件,在6里面被改写成了element
  3. exact:exact属性标识路由使用精确匹配模式,非excat模式下,"/"匹配所有"/"开头的路由,一般都会设置,值可以省略。使浏览器地址栏和我们的匹配规则必须保持一致。

注意:这里组件下只允许存在一个子元素,如存在多个则会报错。

6里面设置默认路由,就给<Route>添加index属性,就是默认渲染,5里面是设置path="/",该组件就是默认组件

<Link>导航组件

Link组件使用以后,他会变成超链接a,的to属性里就写你要跳转的路径

  • Link组件用来处理a链接类似的功能(它会在页面中生成一个a标签),但设置这里需要注意的。react-router-dom拦截了实际a标签的默认动作,然后根据所有使用的路由模式(Hash或者HTML5)来进行处理,改变了URL,但不会发生请求,同时根据Route中的设置把对应的组件显示在指定的位置
  • 属性
  • to(string/object):要跳转的路径或地址:
  • replace(bool):为true时,点击链接后将使用新地址替换掉访问历史记录里面的原地址:为false时,点击链接后将在原有访问历史记录的基础上添加一个新的记录。默认为false,
import React, { Component } from 'react';
import {Routes,Route,Link} from "react-router-dom";
import Index from "./Index";
import Address from './Address';
import About from './About';

export default class App extends Component {
  render() {
    return (
        <div>
            <ul>
                <li><Link to="/">首页</Link></li>
                <li><Link to="/about">about</Link></li>
                <li><Link to="/addr">addr</Link></li>
            </ul>
            <Routes>{/*它相当于老版本的Switch,只要第一个url和path匹配,就不再向下匹配*/}
                <Route path="/"  element={<Index></Index>}/>
                <Route path="/about" element={<About></About>}/>
                <Route path="/addr" element={<Address></Address>}/>
            </Routes>
        </div>
    )
  }
}

单页面和多页面的区别.jpg