你所理解的前端路由是什么?

每日一题-你所理解的前端路由是什么?

  •  为什么会出现前端路由
  • 前端路由解决了什么问题
  • 前端路由实现的原理是什么

传统页面

整个项目都是 DOM直出的页面,“传统页面”(SSR 属于首屏直出,这里我不认为是传统页面的范畴)。那么什么是 DOM直出呢?简单说就是在浏览器输入网址后发起请求,返回来的 HTML页面是最终呈现的效果,那就是 DOM 直出。并且每次点击页面跳转,都会重新请求 HTML 资源。

个传统页面搭建而成的网站,每次加载页面,都会返回 HTML 资源以及里面的 CSS 等静态资源,组合成一个新的页面。

单页面

 React 、 Vue 、 Angular 等著名单页面应用框架。而这些框架有一个共同的特点,便是“通过 JS 渲染页面”。运用这些单页面框架之后, HTML 页面基本上只有一个 DOM 入口

既然单页面是这样渲染的,那如果我有十几个页面要互相跳转切换,咋整!!??这时候 前端路由 应运而生,它的出现就是为了解决单页面网站,通过切换浏览器地址路径,来匹配相对应的页面组件。我们通过一张丑陋的图片来理解这个过程

 

 

前端路由 会根据浏览器地址栏 pathname 的变化,去匹配相应的页面组件。然后将其通过创建 DOM 节点的形式,塞入根节点 <div id="root"></div> 。这就达到了无刷新页面切换的效果,从侧面也能说明正因为无刷新,所以 React 、 Vue 、 Angular 等现代框架在创建页面组件的时候,每个组件都有自己的 生命周期。

原理:哈希模式a 标签锚点大家应该不陌生,而浏览器地址上 # 后面的变化,是可以被监听的,浏览器为我们提供了原生监听事件 hashchange ,它可以监听到如下的变化:

  • 点击 a 标签,改变了浏览器地址
  • 浏览器的前进后退行为
  • 通过 window.location 方法,改变浏览器地址

历史模式 history 模式会比 hash 模式稍麻烦一些,因为 history 模式依赖的是原生事件 popstate ,下面是来自 MDN 的解释:

需要注意的是 调用 history.pushState() 或 history.replaceState() 不会触发popstate事件,只有在做出浏览器动作时,才会触发该时间,如果用户点击浏览器的回退按钮(或者在Javascript代码中调用history.back()或者 history.forward()方法。

小知识:pushState 和 replaceState 都是 HTML5 的新 API,他们的作用很强大,可以做到改变浏览器地址却不刷新页面。这是实现改变地址栏却不刷新页面的重要方法。

包括 a 标签的点击事件也是不会被 popstate 监听。我们需要想个办法解决这个问题,才能实现 history 模式。

解决思路:我们可以通过遍历页面上的所有 a 标签,阻止 a 标签的默认事件的同时,加上点击事件的回调函数,在回调函数内获取 a 标签的 href 属性值,再通过 pushState 去改变浏览器的 location.pathname 属性值。然后手动执行 popstate 事件的回调函数,去匹配相应的路由

为什么需要前端路由?

以前传统的前端都是一个URL对应一个页面,所以不存在这个问题。随着SPA(single-page application)即单页应用的发展,组件的变化和更新不再对应着URL变化了。但是我们又需要这种对应关系(比如通过一个URL直接访问一个 SPA 应用的子视图),我们急需一个工具专门负责维护组件状态与页面URL之间的对应关系,这就是前端路由的作用所在,如 react 的 react-router 和 vue 的 vue-router。

解决问题:

它的出现主要是为了解决单页网站,通过切换浏览器地址url路径,来匹配相对应的页面组件。

使用场景:在单页面应用中,大部分页面结构不变,只改变部分内容时使用。

前端路由优缺点

优点:用户体验好,页面初始化后,只需根据路由变换页面内容,不需要再向服务器发送请求,内容变换快,实现了前后端分离。

缺点:使用浏览器的前进、后退键的时候会重新发送请求,没合理的利用缓存;单页面无法记住之前滚动的位置,无法在前进、后退时记住滚动的位置。

实现原理?

1、哈希模式 #hash

这个模块主要关注 location.hash值,可以通过事件 hashchange 监听 URL的变化,从而跳转到对应的子页面。

2、历史模式

这个模式主要关注 。 location.pathname的值,可以通过事件 popstate 监听URL,但是它有很多局限性,只要做出浏览器动作如用户点击来会退按钮或在JavaScript中调用了 history.back() / history.forward() 才会触发事件,下面这些情况不会触发 popstateshijian :

  • pushState,replaceState(HTML5的心API改变地址栏而不引起页面变化)
  • a标签的点击事件

解决思路:

遍历DOM中所有的a标签,监听click事件,手动pushState改变浏览器地址,并手动调用popState中的回调函数。


参考:https://blog.csdn.net/m0_46171043/article/details/112796220

参考:https://www.lolimay.cn/2021/01/18/web/%E8%B0%88%E8%B0%88%E4%BD%A0%E5%AF%B9%E5%89%8D%E7%AB%AF%E8%B7%AF%E7%94%B1%E7%9A%84%E7%90%86%E8%A7%A3/

参考:https://www.jianshu.com/p/29fb3ec0611c

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值