资讯专栏INFORMATION COLUMN

JS原生一步步实现前端路由和单页面应用

idealcn / 3159人阅读

摘要:这里借鉴了一下的处理方式,我们把多带带模块的包装成一个函数,提供一个全局的回调方法,加载完成时候再调用回调函数。

前端路由实现之 #hash

先上github项目地址: spa-routers
运行效果图

背景介绍

用了许多前端框架来做spa应用,比如说backbone,angular,vue他们都有各自的路由系统,管理着前端的每一个页面切换,想要理解其中路由的实现,最好的方法就是手动实现一个。
前端路由有2种实现方式,一种是html5推出的historyapi,我们这里说的是另一种hash路由,就是常见的 # 号,这种方式兼容性更好。

需求分析

我们这里只是简单的实现一个路由轮子,基本的功能包含以下:

切换页面

异步加载js

异步传参

实现步骤

切换页面:路由的最大作用就是切换页面,以往后台的路由是直接改变了页面的url方式促使页面刷新。但是前端路由通过 # 号不能刷新页面,只能通过 window 的监听事件 hashchange 来监听hash的变化,然后捕获到具体的hash值进行操作

</>复制代码

  1. //路由切换
  2. window.addEventListener("hashchange",function(){
  3. //do something
  4. this.hashChange()
  5. })

注册路由:我们需要把路由规则注册到页面,这样页面在切换的时候才会有不同的效果。

</>复制代码

  1. //注册函数
  2. map:function(path,callback){
  3. path = path.replace(/s*/g,"");//过滤空格
  4. //在有回调,且回调是一个正确的函数的情况下进行存储 以 /name 为key的对象 {callback:xx}
  5. if(callback && Object.prototype.toString.call(callback) === "[object Function]" ){
  6. this.routers[path] ={
  7. callback:callback,//回调
  8. fn:null //存储异步文件状态,用来记录异步的js文件是否下载,下文有提及
  9. }
  10. }else{
  11. //打印出错的堆栈信息
  12. console.trace("注册"+path+"地址需要提供正确的的注册回调")
  13. }
  14. }
  15. //调用方式
  16. map("/detail",function(transition){
  17. ...
  18. })

异步加载js:一般单页面应用为了性能优化,都会把各个页面的文件拆分开,按需加载,所以路由里面要加入异步加载js文件的功能。异步加载我们就采用最简单的原生方法,创建script标签,动态引入js。

</>复制代码

  1. var _body= document.getElementsByTagName("body")[0],
  2. scriptEle= document.createElement("script");
  3. scriptEle.type= "text/javascript";
  4. scriptEle.src= xxx.js;
  5. scriptEle.async = true;
  6. scriptEle.onload= function(callback){
  7. //为了避免重复引入js,我们需要在这里记录一下已经加载过的文件,对应的 fn需要赋值处理
  8. callback()
  9. }
  10. _body.appendChild(scriptEle);

参数传递:在我们动态引入多带带模块的js之后,我们可能需要给这个模块传递一些多带带的参数。这里借鉴了一下jsonp的处理方式,我们把多带带模块的js包装成一个函数,提供一个全局的回调方法,加载完成时候再调用回调函数。

</>复制代码

  1. SPA_RESOLVE_INIT = function(transition) {
  2. document.getElementById("content").innerHTML = "

    当前异步渲染列表页"+ JSON.stringify(transition) +"

    "
  3. console.log("首页回调" + JSON.stringify(transition))
  4. }

扩展:以上我们已经完成了基本功能,我们再对齐进行扩展,在页面切换之前beforeEach和切换完成afterEach的时候增加2个方法进行处理。思路是,注册了这2个方法之后,在切换之前就调用beforeEach,切换之后,需要等待下载js完成,在onload里面进行调用 afterEach

</>复制代码

  1. //切换之前一些处理
  2. beforeEach:function(callback){
  3. if(Object.prototype.toString.call(callback) === "[object Function]"){
  4. this.beforeFun = callback;
  5. }else{
  6. console.trace("路由切换前钩子函数不正确")
  7. }
  8. },
  9. //切换成功之后
  10. afterEach:function(callback){
  11. if(Object.prototype.toString.call(callback) === "[object Function]"){
  12. this.afterFun = callback;
  13. }else{
  14. console.trace("路由切换后回调函数不正确")
  15. }
  16. },

通过以上的思路分析,再加以整合,我们就完成了一个简单的前端路由,并且可以加到页面进行实际的SPA开发,不过还是非常简陋。

完整代码

</>复制代码

  1. /*
  2. *author:https://github.com/kliuj
  3. **使用方法
  4. * 1:注册路由 : spaRouters.map("/name",function(transition){
  5. //异步加载js
  6. spaRouters.asyncFun("name.js",transition)
  7. //或者同步执行回调
  8. spaRouters.syncFun(function(transition){},transition)
  9. })
  10. 2:初始化 spaRouters.init()
  11. 3:跳转 href = "#/name"
  12. */
  13. (function() {
  14. var util = {
  15. //获取路由的路径和详细参数
  16. getParamsUrl:function(){
  17. var hashDeatail = location.hash.split("?"),
  18. hashName = hashDeatail[0].split("#")[1],//路由地址
  19. params = hashDeatail[1] ? hashDeatail[1].split("&") : [],//参数内容
  20. query = {};
  21. for(var i = 0;i
  22. 简单的单页面在github上有完整的demo
    spa-routers

  23. 以上仅是我个人的一些看法,如有疑问,感谢指导

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/80805.html

相关文章

  • 基于 Webpack 4 多入口生成模板用于服务端渲染的方案及实战

    摘要:原作者原链接基于多入口生成模板用于服务端渲染的方案及实战法律声明警告本作品遵循署名非商业性使用禁止演绎未本地化版本协议发布。这是什么背景现代化的前端项目中很多都使用了客户端渲染的单页面应用。 原作者:@LinuxerPHL原链接:基于 Webpack 4 多入口生成模板用于服务端渲染的方案及实战 法律声明 警告:本作品遵循 署名-非商业性使用-禁止演绎3.0 未本地化版本(CC BY-...

    big_cat 评论0 收藏0
  • 基于 Webpack 4 多入口生成模板用于服务端渲染的方案及实战

    摘要:原作者原博文地址基于多入口生成模板用于服务端渲染的方案及实战法律声明警告本作品遵循署名非商业性使用禁止演绎未本地化版本协议发布。这是什么背景现代化的前端项目中很多都使用了客户端渲染的单页面应用。 原作者:@LinuxerPHL原博文地址: 基于 Webpack 4 多入口生成模板用于服务端渲染的方案及实战 法律声明 警告:本作品遵循 署名-非商业性使用-禁止演绎3.0 未本地化版本(...

    Lavender 评论0 收藏0
  • 张脑图看懂BUI Webapp移动快速开发框架【上】--框架与工具、资源

    摘要:后续我们还会增加一些实战类的移动开发案例,欢迎关注专栏。进入官网新版预览在线预览需要使用开启设备模拟,效果更佳。 前言 之前写过一篇 2018开发最快的Webapp框架--BUI交互框架 ,如果你还没看过,可以简单看一下,主要介绍了BUI的基本功能,有多少控件,以及实现的思路,BUI 1.5版本以后变化很大,统一新的风格,新的规范750,新增基于Dom的数据驱动,完善了页面的生命周期等...

    wuyumin 评论0 收藏0
  • SPA那点事

    摘要:单页面应用的出现依然存在着争议性,我们该如何看待他的两面性呢接下来小生给大家总结一下他的优缺点。单页面应用的优势无刷新体验没有了令人诟病的页面频繁刷新,同时节约浏览器资源,路由响应比较及时,提升了用户的体验。 前端猿一天不学习就没饭吃了,后端猿三天不学习仍旧有白米饭摆于桌前。IT行业的快速发展一直在推动着前端技术栈在不断地更新换代,前端的发展成了互联网时代的一个缩影。而单页面应用的发展...

    PumpkinDylan 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<