作者:@whinc链接:https://github.com/whinc/blog/issues/13

在单页应用如此流行的今天,曾经令人惊叹的前端路由已经成为各大框架的基础标配,每个框架都提供了强大的路由功能,导致路由实现变的复杂。想要搞懂路由内部实现还是有些困难的,但是如果只想了解路由实现基本原理还是比较简单的。本文针对前端路由主流的实现方式 hash 和 history,提供了原生JS/React/Vue 共计六个版本供参考,每个版本的实现代码约 25~40 行左右(含空行)。

什么是前端路由?

路由的概念来源于服务端,在服务端中路由描述的是 URL 与处理函数之间的映射关系。

在 Web 前端单页应用 SPA(Single Page Application)中,路由描述的是 URL 与 UI 之间的映射关系,这种映射是单向的,即 URL 变化引起 UI 更新(无需刷新页面)。

如何实现前端路由?

要实现前端路由,需要解决两个核心:

  • 如何改变 URL 却不引起页面刷新?
  • 如何检测 URL 变化了?

下面分别使用 hash 和 history 两种实现方式回答上面的两个核心问题。

hash 实现

  • hash 是 URL 中 hash (#) 及后面的那部分,常用作锚点在页面内进行导航,改变 URL 中的 hash 部分不会引起页面刷新
  • 通过 hashchange 事件监听 URL 的变化,改变 URL 的方式只有这几种:通过浏览器前进后退改变 URL、通过标签改变 URL、通过window.location改变URL,这几种情况改变 URL 都会触发 hashchange 事件

history 实现

  • history 提供了 pushState 和 replaceState 两个方法,这两个方法改变 URL 的 path 部分不会引起页面刷新
  • history 提供类似 hashchange 事件的 popstate 事件,但 popstate 事件有些不同:通过浏览器前进后退改变 URL 时会触发 popstate 事件,通过pushState/replaceState或标签改变 URL 不会触发 popstate 事件。好在我们可以拦截 pushState/replaceState的调用和标签的点击事件来检测 URL 变化,所以监听 URL 变化可以实现,只是没有 hashchange 那么方便。

原生JS版前端路由实现

基于上节讨论的两种实现方式,分别实现 hash 版本和 history 版本的路由,示例使用原生 HTML/JS 实现,不依赖任何框架。

基于 hash 实现

运行效果:

HTML 部分:

JavaScript 部分:

基于 history 实现

运行效果:

HTML 部分:

 
  • home
  • about

JavaScript 部分:

React 版前端路由实现

基于 hash 实现

运行效果:

使用方式和 react-router 类似:

 

home about

Home

} />

About

} />

BrowserRouter 实现

Route 实现

export default ({ path, render }) => (  {({currentPath}) => currentPath === path && render()} );

Link 实现

export default ({ to, ...props }) => ;

基于 history 实现

运行效果:

使用方式和 react-router 类似:

 

home about

Home

} />

About

} />

HistoryRouter 实现

Route 实现

export default ({ path, render }) => (  {({currentPath}) => currentPath === path && render()} );

Link 实现

Vue 版本前端路由实现

基于 hash 实现

运行效果:

使用方式和 vue-router 类似(vue-router 通过插件机制注入路由,但是这样隐藏了实现细节,为了保持代码直观,这里没有使用 Vue 插件封装):

 
home about

router-view 实现

router-link 实现

基于 history 实现

运行效果:

使用方式和 vue-router 类似:

 
home about

router-view 实现:

router-link 实现

小结

前端路由的核心实现原理很简单,但是结合具体框架后,框架增加了很多特性,如动态路由、路由参数、路由动画等等,这些导致路由实现变的复杂。本文去粗取精只针对前端路由最核心部分的实现进行分析,并基于 hash 和 history 两种模式,分别提供原生JS/React/Vue 三种实现,共计六个实现版本供参考,希望对你有所帮助。

所有的示例的代码放在 Github 仓库:https://github.com/whinc/web-router-principle

参考

  • 详解单页面路由的几种实现原理
  • http://www.cnblogs.com/xiaobie123/p/6357724.html
  • 单页面应用路由实现原理:以 React-Router 为例
  • https://github.com/youngwind/blog/issues/109

react router 级联路由_前端路由原理解析和实现相关推荐

  1. c语言实现路由功能,前端路由的两种实现方式,内附详细代码

    一.前端路由介绍 前端路由主要应用在SPA(单页面开发)项目中.在无刷新的情况下,根据不同的URL来显示不同的组件或者内容. 前端路由的实现原理 : hash值 + onhashchange事件 hi ...

  2. 路由【前端路由和后端路由】(在这吹不出褶皱的平静日子,你也在闪闪发光)

    1.路由:程序开发的路由顾名思义:分为前端路由和后端路由. 2.后端路由:常说的后端路由通过用户请求的url分布到具体的处理程序,服务器接受到之后,返回HTML页面或直接渲染HTNL模板 简单点来说: ...

  3. 父页面监听iframe路由变化_前端路由原理

    对于前端路由应该都很熟悉了,开发过spa应用的应该都用过,只是很少人去查一下前端路由实现的原理. 前端路由的实现核心问题有两个,一个是改变url不刷新,另一个是监听url变化.主要靠的就是hash和h ...

  4. hitchhiker部署_《 Hitchhiker的React Router v4指南》:路由配置的隐藏值

    hitchhiker部署 Welcome to the Hitchhiker's Guide to React Router v4, Part IV! 欢迎来到< React Router v4 ...

  5. history 改成 模式_前端路由三种模式

    hash:任何情况下都可以做前端路由,缺点是SEO不友好(服务器收不到hash,浏览器是不会把#后面的内容发给服务器) history模式:后端将所有前端路由都渲染到同一个页面(不能是404页面),缺 ...

  6. reactrouter监听路由变化_前端路由三种模式

    hash:任何情况下都可以做前端路由,缺点是SEO不友好(服务器收不到hash,浏览器是不会把#后面的内容发给服务器) history模式:后端将所有前端路由都渲染到同一个页面(不能是404页面),缺 ...

  7. 没有配置默认路由_网络路由选择原理

    一:什么是路由 路由(routing)是指分组从源到目的地时,决定端到端路径的网络范围的进程. 路由器两个重要的功能 ①维护路由表 ②根据收到的数据包中目的网络地址与路由表中路由条目进行匹配,确定转发 ...

  8. 什么是`前端路由`?什么时候使用`前端路由`?`前端路由`存在哪些优缺点?

    一.前言 之前我们前后端开发采用前后端分离的方法,现在的前后端开发我们采用SPA来开发,也就是单页面开发应用. 我们在采用前后端分离的方法进行开发时,我们请求一个url地址,此时后台返回给我们一个页面 ...

  9. linux 软路由_软路由和硬路由的区别分析

    路由器--作为大型网络场所必须的产品,许多企业IT网络管理者在选择路由器时左右抉择,不知选择哪种更合适. 相对于硬路由来说呢,软路由的技术要求相对更高.不过其实只要你动脑去研究,就会发现软路由不过如此 ...

最新文章

  1. 《Offer一箩筐》2W字总结面试套路14问——不给例子的教程都是耍流氓!!
  2. puppeteer(headless chrome)实现网站登录
  3. 7种从头开始免费学习编程的方法
  4. Python 技术篇-用PIL库修改图片透明度实例演示,改变png图片色道为RGBA、RGB
  5. 04_Struts2标签
  6. ISE如何封装与使用IP —— 使用ngc文件与仅包含端口的v文件
  7. Entity Framework 6 Recipes 2nd Edition(12-1)译 - 当SaveChanges( ) 被调用时执行你的代码...
  8. 鸿蒙电视应用市场,任正非:鸿蒙系统已上线,未来将被应用到手机、平板、电视系列产品上...
  9. 使用UITextField去自定义searchBar 【iOS】
  10. VS2017离线下载 -- 如何让VS2017不占用C盘
  11. 【JavaScript】去除空格
  12. 【C++学习五】STL库的应用
  13. Excel两列数据对比,找出重复数据
  14. Photoshop插件-证件照-2寸裁剪-2寸排版-脚本开发-PS插件
  15. 靶点c语言,降脂治疗靶点:LDL-C是最好的吗?(上)
  16. 求1-1/2+1/3-1/4+.......+1/99-1/100的值
  17. 任正非最新讲话:最好的防御就是进攻
  18. 全球及中国呼叫中心服务行业运营模式及发展战略分析报告2022-2028年
  19. 流量高的短视频有哪些特点?三个共同点分享,助你找准方向
  20. CGAN(conditional GANs)

热门文章

  1. 数据与程序分离——程序中那些表的事儿
  2. 网络营销的探索与爆发
  3. 如何在Simulink中添加延迟环节
  4. Android开源SIP协议栈比较
  5. matlab中print、fprintf、scanf、disp函数简要语法介绍
  6. linux下使用expect+scp+shell实现分布式集群系统安装,升级,部署
  7. 设计模式-结构型-桥接
  8. html下拉框只读,HTML元素(如select下拉框)设置为只读
  9. 用Docker搭建Nexus私服
  10. mysql查询字符串出现次数