时隔16年Jeff Barr重返10.23-25 QCon上海站,带你看透AI如何重塑软件开发! 了解详情
写点什么

造轮子——前端路由

  • 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:18991

评论

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

软件测试过程中的痛点思考

老张

提升效率 质量保障

算法人生(1):从“强化学习”看如何“战胜拖延”

糖小妹来了

算法 拖延症 强化学习 走出拖延 拖延

【论文速读】| LLM4FUZZ:利用大语言模型指导智能合约的模糊测试

云起无垠

深入理解分布式锁:原理、应用与挑战| 京东物流技术团队

京东科技开发者

云南等级保护测评机构有哪些?分别在哪里?

行云管家

等保 堡垒机 云南 等保测评机构

RWA会成为下一个风口吗?有哪些值得关注的项目?

区块链软件开发推广运营

dapp开发 区块链开发 链游开发 NFT开发 公链开发

GaussDB细粒度资源管控技术透视

华为云开发者联盟

数据库 华为云 华为云GaussDB 华为云开发者联盟 企业号2024年5月PK榜

深入理解java反射机制及应用 | 京东物流技术团队

京东科技开发者

算法人生(3):从“贪心算法”看“战胜拖延”(完美主义版)

糖小妹来了

算法 拖延症 贪心算法 走出拖延 拖延

算法人生(4):从“选项学习”看“战胜拖延”(担心失败版)

糖小妹来了

算法 强化学习 走出拖延 拖延 选项学习

算法人生(5):从“元学习”看“战胜拖延”(没兴趣版)

糖小妹来了

机器学习 算法 元学习 走出拖延 拖延

算法人生(8):从“注意力算法”看“战胜拖延”(被分心太多版)

糖小妹来了

深度学习 算法 走出拖延 拖延 注意力算法

一种极简单的SpringBoot单元测试方法| 京东零售技术团队

京东科技开发者

算法人生(2):从“强化学习”看如何“活在当下”

糖小妹来了

算法 活在当下 强化学习

算法人生(9):从“贝叶斯更新”看“战胜拖延”(消极预期版)

糖小妹来了

机器学习 算法 贝叶斯算法 走出拖延 拖延

“三个办法”新规将于7月1日起施行

芯盾时代

金融 风控 信贷

ChatGPT-5最新消息;预计包含Sora模型;附最新使用教程

蓉蓉

openai ChatGPT4

目前市面上堡垒机厂家有哪些?会帮忙部署吗?

行云管家

网络安全 数据安全 数据加密 堡垒机

什么? 20分钟,构建你自己的LLaMA3应用程序| 京东云技术团队

京东科技开发者

测试答疑助手:从需求文档到设计文档、测试用例的完整测试过程

霍格沃兹测试开发学社

一键自动化博客发布工具,用过的人都说好(cnblogs篇)

程序那些事

自动化 工具 程序那些事 自动发布

算法人生(6):从“反馈学习”看“战胜拖延”(被动攻击版)

糖小妹来了

算法 强化学习 走出拖延 拖延 反馈学习

算法人生(7):从“时间折扣策略”看“战胜拖延”(等待最佳时机版)

糖小妹来了

算法 强化学习 走出拖延 拖延 时间折扣

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