50万奖金+官方证书,深圳国际金融科技大赛正式启动,点击报名 了解详情
写点什么

造轮子——前端路由

  • 2020-04-03
  • 本文字数:2036 字

    阅读完需:约 7 分钟

造轮子——前端路由

前端路由

现代前端开发中最流行的页面模型,莫过于 SPA 单页应用架构。单页面应用指的是应用只有一个主页面,通过动态替换 DOM 内容并同步修改 url 地址,来模拟多页应用的效果,切换页面的功能直接由前台脚本来完成,而不是由后端渲染完毕后前端只负责显示。前端三驾马车 Angular,Vue,React 均基于此模型来运行的。SPA 能够以模拟多页面应用的效果,归功于其前端路由机制。


前端路由,顾名思义就是一个前端不同页面的状态管理器,可以不向后台发送请求而直接通过前端技术实现多个页面的效果。angularjs 中的 ui-router,vue 中的 vue-router,以及 react 的 react-router 均是对这种功能的具体实现。


既然前端路由这么牛逼,那必须的好好研究一下。

两种实现方式及其原理

常见的路由插件中两种方式都是支持且可以切换的,例如 angularjs1.x 中就可以通过以下代码从 Hash 模式切换到 H5 模式:


$locationProvider.html5Mode(true);


切换到 HTML5 的路由模式,主要用于避免 url 地址中包含 #而引发的问题。


HashChange


  • 原理

  • HTML 页面中通过锚点定位原理可进行无刷新跳转,触发后 url 地址中会多出 # + 'XXX’的部分,同时在全局的 window 对象上触发 hashChange 事件,这样在页面锚点哈希改变为某个预设值的时候,通过代码触发对应的页面 DOM 改变,就可以实现基本的路由了,基于锚点哈希的路由比较直观,也是一般前端路由插件中最常用的方式。

  • 应用

  • 下面通过一个实例看一下,当点击 angularjs 的连接时,可以看到控制台打印出了相应的信息。




HTML5 HistoryAPI


  • 原理

  • HTML5 的 History API 为浏览器的全局 history 对象增加的扩展方法。一般用来解决 ajax 请求无法通过回退按钮回到请求前状态的问题。


在 HTML4 中,已经支持 window.history 对象来控制页面历史记录跳转,常用的方法包括:


history.forward(); //在历史记录中前进一步history.back(); //在历史记录中后退一步history.go(n): //在历史记录中跳转n步骤,n=0为刷新本页,n=-1为后退一页。
在HTML5中,window.history对象得到了扩展,新增的API包括:history.pushState(data[,title][,url]);//向历史记录中追加一条记录history.replaceState(data[,title][,url]);//替换当前页在历史记录中的信息。history.state;//是一个属性,可以得到当前页的state信息。window.onpopstate;//是一个事件,在点击浏览器后退按钮或js调用forward()、back()、go()时触发。回调函数中可传入一个event对象,event.state即为通过pushState()或replaceState()方法传入的data参数。
复制代码


  • 应用

  • 浏览器访问一个页面时,当前地址的状态信息会被压入历史栈,当调用 history.pushState()方法向历史栈中压入一个新的 state 后,历史栈顶部的指针是指向新的 state 的。可以将其作用简单理解为假装已经修改了 url 地址并进行了跳转 ,除非用户点击了浏览器的前进,回退,或是显式调用 HTML4 中的操作历史栈的方法,否则不会触发全局的 popstate 事件。


在下面的示例中,点击导航按钮,可以看到 url 地址栏发生了变化,且控制台打印出了响应的信息。




hash 和 history API 对比


亲手造一个简单的前端路由插件

造轮子,不是为了把它装在你的车上,而是当你在荒郊野外开车而轮子出了问题时多一种选择。


接下来就自己动手实现一个前端路由的插件吧~


  • 基于 Hash 的前端路由插件 myHashRouter.js


我们希望实现的功能是:


1.引入 MyHashRouter.js 库


2.通过 when()方法来定义若干不同的路由状态


3.通过 init()方法启动路由功能


4.通过点击导航实现前端路由切换


首先编写 js 骨架,如下所示:



完成了路由插件的编写后,我们在 demo 中引入该库,然后使用 when()方法注册几个路由地址,再使用 init()方法启动路由,脚本部分代码如下:



效果:运行附件中的 router-demo-hash.html,点击导航按钮,即可看到 url 地址栏以及内容区域同步更改。


  • 基于 History API 的前端路由插件 myHistoryRouter.js

  • 由于 History API 不支持低于 IE10 以下版本的浏览器(其他大多数现代浏览器基本都支持),所以我们在 init()方法启动时先进行可用性判断,基本代码框架与基于 Hash 的路由插件一致。每个方法的实现并不难写,这里不再赘述,笔者自己的代码实现放在附件 myHistoryRouter.js 中,水平有限,仅供参考。


效果:



  • 集成说明

  • 为方便理解,本例中将两种模式分开编写,如果是插件库的开发,可以模仿 ui-router 增加一个 html5mode()的方法,在 init()方法启动路由时,根据所传的参数生成不同的路由插件的单例,也就是我们常说的工厂模式来实现即可。

后记

造车轮是一个很好的学习方式,虽然自己造的车轮很简陋,但是对于理解工具的底层原理却很有帮助。


本例只是编写了一个路由工具的基本骨架,真正的路由工具还需要做很多功能扩展,个别功能的复杂度也会很高,例如路径的正则匹配,懒加载,组合视图,嵌套视图,路由动画等等,有兴趣的小伙伴可以在本例提供的框架上进行学习扩展。

附件

myHashRouter.js 源码:



本文转载自华为云产品与解决方案公众号。


原文链接:https://mp.weixin.qq.com/s/tsKI3s9G7lSwH0QwyGBgWA


2020-04-03 17:181003

评论

发布
暂无评论
发现更多内容

nsq源码阅读之Topic

werbenhu

nsq Go 语言

Swift 5创建和使用Framework, XCFramework 从入门到精通 John 易筋 ARTS 打卡 Week 42

John(易筋)

ARTS 打卡计划 Framework XCFramework

Python-计算机视觉-OpenCV-调色板

Aldeo

Python OpenCV

想学IT的必看!漫谈MySQL权限安全,分享一点面试小经验

欢喜学安卓

android 程序员 面试 移动开发

下一站,星辰大海!

百度大脑

百度 AI 上市

推荐35款可以快速提升工作效率的软件

科技猫

软件 经验分享 实用工具 办公 工具分享

hive的DQL查询语法详细剖析

大数据技术指南

大数据 hive 3月日更

Dubbo的设计理念原来就藏在这三张图中

中间件兴趣圈

dubbo RPC

超全Android中高级面试复习大纲,在线面试指南

欢喜学安卓

android 程序员 面试 移动开发

使用Redis,你必须知道的21个注意要点

Java 数据库 redis 架构 面试

SDK介绍及相关功能测试

行者AI

测试 sdk

快速使用Vue3最新的15个常用API(1W5+字详解,建议收藏)

零一

vue.js 大前端 Vue3

4层板到12层板叠层经典设计方案

不脱发的程序猿

28天写作 电路设计 3月日更 PCB PCB布局

【LeetCode】扁平化嵌套列表迭代器Java题解

Albert

算法 LeetCode 3月日更

nsq源码阅读之Channel

werbenhu

nsq Go 语言

nsq源码阅读之消息接收和发送

werbenhu

nsq Go 语言

到底什么是Event Loop?那就来了解一下JavaScript分别在浏览器和Node环境下的运行机制吧

零一

JavaScript 大前端

nsq源码阅读之diskqueue

werbenhu

nsq Go 语言

DB-Engines 3月数据库排名:MySQL跳出“同期跌幅榜”,拿下“本月涨幅榜冠军”

华章IT

数据库

nsq源码阅读之nsqd总体流程

werbenhu

nsq Go 语言

Netty 核心源码解读 —— ServerBootstrap 篇

松然聊技术

Netty

硬件工程师必备,常用元器件封装速查表

不脱发的程序猿

28天写作 电路设计 3月日更 元器件封装速查表 电子设计

如何在3分钟内实现音频变声和趣味音效?

拍乐云Pano

音视频 RTC 出海社交 社交泛娱乐

SQLServer性能调优方法小结

嘉为蓝鲸

数据库 sql 运维 SqlServer MAXDOP

Redis新版本开始引入多线程,谈谈你的看法?

Java架构师迁哥

Python 高手都这样使用字典,这些高效方法你知道吗?|pythonic 小技巧

AlwaysBeta

Python

Netty 核心源码解读 —— 开篇

松然聊技术

Netty

已拿到蚂蚁金服Offer!阿里内部二十三万字Java面试题总结

Java架构追梦

Java 阿里巴巴 架构 面试 金三银四

阿里一战封神,百万人跪求的Java面试手册终于开源;

Java架构师迁哥

智慧公安重点人员系统开发,情报研判管控平台的搭建

13828808769

行业资讯

图解TCP的通信机制

零一

TCP 网络

造轮子——前端路由_文化 & 方法_华为云产品与解决方案_InfoQ精选文章