React路由

React路由

一 对SPA应用的理解

需要理解的概念有:

  • 什么是SPA
  • SPA和MPA的区别
  • 实现一个SPA
  • 如何给SPA做SEO
  • SPA与MPA网站演示

1.什么是SPA

  1. 单页web应用(single-page application),翻译过来就是单页应用。

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

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

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

img

2.SPA和MPA的区别

上面大家已经对单页面有所了解了,下面来讲讲多页应用。

MPA(MultiPage-page application),翻译过来就是多页应用。

在MPA中,每个页面都是一个主页面,都是独立的。

当我们在访问另一个页面的时候,都需要重新加载html、css、js文件,公共文件则根据需求按需加载。

如下图

image-20210519074843121

单页应用与多页应用的区别

单页面应用(SPA) 多页面应用(MPA)
组成 一个主页面和多个页面片段 多个主页面
刷新方式 局部刷新 整页刷新
url模式 哈希模式 历史模式
SEO搜索引擎优化 难实现,可使用SSR方式改善 容易实现
数据传递 容易 通过url、cookie、localStorage等传递
页面切换 速度快,用户体验良好 切换加载资源,速度慢,用户体验差
维护成本 相对容易 相对复杂

单页应用优势与不足

优点:

  • 具有桌面应用的即时性、网站的可移植性和可访问性
  • 用户体验好、快,内容的改变不需要重新加载整个页面
  • 良好的前后端分离,分工更明确

不足:

  • 不利于搜索引擎的抓取
  • 首次渲染速度相对较慢

3.实现一个SPA

原理

  1. 监听地址栏中hash变化驱动界面变化
  2. pushsate记录浏览器的历史,驱动界面发送变化

image-20210519075226296

实现

hash 模式

核心通过监听url中的hash来进行路由跳转

// 定义 Router
class Router {
   
    constructor () {
   
        this.routes = {
   }; // 存放路由path及callback
        this.currentUrl = '';
        
        // 监听路由change调用相对应的路由回调
        window.addEventListener('load', this.refresh, false);
        window.addEventListener('hashchange', this.refresh, false);
    }
    
    route(path, callback){
   
        this.routes[path] = callback;
    }
    
    push(path) {
   
        this.routes[path] && this.routes[path]()
    }
}
 
// 使用 router
window.miniRouter = new Router();
miniRouter.route('/', () => console.log('page1'))
miniRouter.route('/page2', () => console.log('page2'))
 
miniRouter.push('/') // page1

history模式
history 模式核心借用 HTML5 history api,api 提供了丰富的 router 相关属性

先了解一个几个相关的api history.pushState 浏览器历史纪录添加记录
history.replaceState修改浏览器历史纪录中当前纪录
history.popState 当 history 发生变化时触发

// 定义 Router
class Router {
   
    constructor () {
   
        this.routes = {
   };
        this.listerPopState()
    }
    
    init(path) {
   
        history.replaceState({
   path: path}, null, path);
        this.routes[path] && this.routes[path]();
    }
    
    route(path, callback){
   
        this.routes[path] = callback;
    }
    
    push(path) {
   
        history.pushState({
   path: path}, null, path);
        this.routes[path] && this.routes[path]();
    }
    
    listerPopState () {
   
        window.addEventListener('popstate' , e => {
   
            const path = e.state && e.state.path;
            this.routers[path] && this.routers[path]()
        })
    }
}
 
// 使用 Router
 
window.miniRouter = new Router();
miniRouter.route('/', ()=> console.log('page1'))
miniRouter.route('/page2', ()=> console.log('page2'))
 
// 跳转
miniRouter.push('/page2')

4.如何给SPA做SEO

面给出基于Vue的SPA如何实现SEO的三种方式:

  • SSR服务端渲染

将组件或页面通过服务器生成html,再返回给浏览器,如nuxt.js

  • 静态化

目前主流的静态化主要有两种:

(1)一种是通过程序将动态页面抓取并保存为静态页面,这样的页面的实际存在于服务器的硬盘中

(2)另外一种是通过WEB服务器的 URL Rewrite的方式,它的原理是通过web服务器内部模块按一定规则将外部的URL请求转化为内部的文件地址,一句话来说就是把外部请求的静态地址转化为实际的动态页面地址,而静态页面实际是不存在的。这两种方法都达到了实现URL静态化的效果

  • 使用Phantomjs针对爬虫处理

原理是通过Nginx配置,判断访问来源是否为爬虫,如果是则搜索引擎的爬虫请求会转发到一个node server,再通过PhantomJS来解析完整的HTML,返回给爬虫。

image-20210519075437627

5.SPA与MPA网站演示

SPA:www.qiniu.com、阿里云平台、腾讯云平台等

MPA:www.163.com

二 对路由的理解

需要理解的概念有:

  • 路由概念的核心词汇:静态路由表,分配地址,统一入口,寻址以及过滤

  • 什么是路由:

    1 一个路由就是一个映射关系(key.value)

    2 key为路径,value可能是function或component

  • 路由的分类

    1 后端路由:

    ​ ① 理解:value是function,用来处理客户端提交的请求

    ​ ② 注册路由:router.get(path,function(req,res))

    ​ ③ 工作过程:当node接受到一个请求时,根据请求路径找到匹配的路由,条用路由中的函数来处理请求,返回响应数据

    2 前端路由:

    ​ ① 浏览器路由:value是component,用于展示页面内容

    ​ ② 注册路由:

    ​ ③ 工作过程:当浏览器的path变成/test时,当前路由组件就会变成Test组件

image-20210519073903643

对于路由的功能实现原理现在可以大致做个剖析,它其实是提供了一种方式给各个场景之间进行切换操作并且管理其导航历史,每个场景都像一图层,可以推送至其它场景的最后面,当然,如果你将它删除就无法实现该操作了。我们尝试以一种更容易理解的方式进行解释,就是将路由理解成翻书操作,所有的页面就是我们配置的路由模块,可以将书本翻至某一页,也就是其中某一模块,也可以翻到另一页,另一个模块内容,当然,如果需要,还是可以翻回到刚才的那一页的,前提是你不能把那页纸给撕了。

三 前端路由原理

需要理解的概念有:

  • HTML+CSS能否实现SPA项目
  • 前端路由实现原理的核心模块是什么
  • 前端路由的跳转模式主要有哪些
  • 锚点与历史跳转的差异

利用HTML+CSS实现的SPA:http://qn.chinavanes.com/anchor-router.zip

前端路由实现原理的核心模块:https://github.com/ReactTraining/history

  1. history库
  • 管理浏览器会话历史(history)的工具库
  • 包装的是原生BOM中window.history和window.location.hash
  1. history API
  • History.createBrowserHistory(): 得到封装window.history的管理对象
  • History.createHashHistory(): 得到封装window.location.hash的管理对象
  • history.push(): 添加一个新的历史记录
  • history.replace(): 用一个新的历史记录替换当前的记录
  • history.goBack(): 回退到上一个历史记录
  • history.goForword(): 前进到下一个历史记录
  • history.listen(function(location){}): 监视历史记录的变化

前端路由实现原理核心模块的应用:http://qn.chinavanes.com/history-router.zip

四 路由的基本使用

需要理解的概念有:

  • react-router各个模块包的功能与差异
  • React-router的核心API有哪些

1.react-router各个模块包的功能与差异

react-router的github地址:https://github.com/ReactTraining/react-router
react-router的官网项目地址:https://reactrouter.com/

react-router的理解:

  • react的一个插件库
  • 专门用来实现一个SPA应用
  • 基于react的项目基本都会用到此库

1、React-router与React-router-dom的功能对比
React-router:实现了路由的核心功能
React-router-dom:基于React-router,加入了一些在浏览器运行下的一些功能,
例如:Link组件会渲染一个a标签
BrowserRouter使用 HTML5 提供的 history API可以保证你的 UI 界面和 URL 保持同步
HashRouter使用 URL 的 hash 部分保证你的 UI 界面和 URL 保持同步

2、React-router与React-router-dom的API对比
React-router:提供了router的核心api。如Router、Route、Switch等,但没有提供有关dom操作进行路由跳转的API
React-router-dom:提供了BrowserRouter、Route、Link等API,可以通过dom操作触发事件控制路由

2.React-router的核心API有哪些

BrowserRouter 浏览器模式路由,PC端
HashRouter Hash值模式路由,PC端
Link 普通链接
NavLink 导航链接
Prompt 提示
MemoryRouter 内存模式路由,ReactNative移动端
Redirect 重定向
Route 单个路由对象
Router 整体路由对象
StaticRouter 静态路由,SSR服务器端渲染使用
Switch 选择路由
generatePath 生成路由地址
history 历史
location 地址
match 匹配
matchPath 匹配路径
withRouter 接收路由的HOC组件

3.创建基本路由切换

src/components/Home/index.js

import React, { Component } from 'react';

export default class Home extends Component {
	render() {
		return <div>我是Home组件</div>;
	}
}

src/components/About/index.js

import React, { Component } from 'react';

export default class About extends Component {
	render() {
		return <div>我是About组件</div>;
	}
}

3.1注册路由,设置静态路由表,并且分配地址

src/App.js 安装react-router-dom

目前报错:Error: Invariant failed: You should not use <Link> outside a <Router>

import React, { Component } from 'react';
import { Route } from 'react-router-dom';
import Home from './components/Home';
import About from './components/About';

class App extends Component {
	render() {
		return (
			<div>
				<div className='row'>
					<div className='col-xs-offset-2 col-xs-8'>
						<div className='page-header'>
							<h2>React Router Demo</h2>
						</div>
					</div>
				</div>
				<div className='row'>
					<div className='col-xs-2 col-xs-offset-2'>
						<div className='list-group'>
							<a className='list-group-item' href='./about.html'>
								About
							</a>
							<a className='list-group-item active' href='./home.html'>
								Home
							</a>
						</div>
					</div>
					<div className='col-xs-6'>
						<div className='panel'>
							<div className='panel-body'>
								{/* 注册路由:设置静态路由表,并且分配路由地址 */}
								<Route path='/about' component={About} />
								<Route path='/home' component={Home} />
							</div>
						</div>
					</div>
				</div>
			</div>
		);
	}
}
export default App;

3.2利用BrowserRoute进行静态路由表的包含

Route是什么?Route是路由

BrowserRouter与Route的关系是什么?

Router代表的是一整个路由对象,它是数组

Route是整个路由对象中的其中一个而已,是单一的路由模块对象

import React, { Component } from 'react';
import { Route, BrowserRouter } from 'react-router-dom';
import Home from './components/Home
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值