谈谈你对前端路由的理解
为什么需要前端路由?
以前传统的前端都是一个URL对应一个页面,所以不存在这个问题。随着SPA(single-page application)即单页应用的发展,组件的变化和更新不再对应着URL变化了。但是我们又需要这种对应关系(比如通过一个URL直接访问一个 SPA 应用的子视图),我们急需一个工具专门负责维护组件状态与页面URL之间的对应关系,这就是前端路由的作用所在,如 react 的 react-router 和 vue 的 vue-router。
实现原理?
- 哈希模式
#hash
这个模式主要关注 location.hash
值,可以通过事件 hashchange
监听 URL 的变化,从而去跳转到对应子页面。
- 历史模式
这个模式主要关注 location.pathname
的值,可以通过事件 popstate
监听 URL,但是它有很多局限性,只有做出浏览器动作如用户点击了回退按钮或在JavaScript中调用了history.back()/history.forwad()才会触发事件,下面这些情况不会触发 popstate
事件:
- pushState, replaceState (HTML5 的新 API 改变地址栏而不引起页面变化)
- a 标签的点击事件
解决思路:
遍历 DOM 中所有的 a 标签,监听 click 事件,手动 pushState 改变浏览器地址,并手动调用 popState 中的回调函数。