「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」
hash 模式
早期的前端路由是基于 location.hash 来实现的,原理其实很简单,location.hash 的是就是 URL 后面#号的值,如下:
https:// blog.codedogs.top#index
前面这个网址的 location.hash 就是#index
hash 路由模式的实现主要是基于以下几个特性:
- URL 中的 hash 值只是客户端的一种状态,也就是说向服务器发送请求时,hash 部分不会发送到服务器
- hash 值的改变,都会在浏览器的访问历史中增加一个记录,因此可以前进后退控制访问记录
- 可以通过 a 标签,并且设置 href 属性,当用户点击这个标签后,URL 的 hash 值会发生改变;或者使用 JavaScript 来对 location.hash 进行赋值,改变 URL 的 hash 值
- 我们可以使用 haschange 事件来监听 hash 值的变化,从而对页面进行跳转(渲染)
history 模式
HTML5 提供了 History API 来实现 URL 的变化,其中主要的 API 有以下两个: history.pushState() 和 history.repalseState(),这两个 API 可以在不进行刷新的情况下,操作浏览器的历史记录,唯一不同的是,前者是新增一个历史记录,后者是直接替换当前的历史记录,如下所示:
window.history.pushState(null,null,path)
window.history.replaceState(null,null,path)
history 路由模式的实现主要基于存在以下几个特性
- pushState 和 replaceState 两个 API 来操作实现 URL 的变化
- 我们可以使用 popstate 事件来监听 URL 的变化,从而对页面进行跳转(渲染)
- history.pushState() 或 history,resplaceState()不会触发 popstate 事件,这时候我们需要手动触发页面跳转(渲染)
history 的问题
History 的路由模式虽然好看,但是还需要后台的配置,因为前台是单页面应用,后台没有正确的配置就是会返回 404 了
所以,在服务端需要增加一个覆盖所有情况的候选资源,如果 URL 匹配不到任何静态资源,则应该返回 index.html 页面,这个页面就是 app 的依赖页面。
简单实现 vue Routher
Vue Router 核心是,通过 Vue.use 注册插件,在插件的 install 方法中获取用户设置的 router 对象,当前浏览器对象发生变化时,根据 router 对象匹配相应的路由,获取组件,并将该组件渲染到视图上。
- 如何在 install 方法获取 Vue 实例上的 router 属性
可以利用 Vue.mixin 混入生命周期函数 beforeCreate,在 beforeCreate 函数中可以获取到 Vue 实例上的属性并赋值到 Vue 原型链上。
_Vue.mixin({
if(this.$options.router){
_Vue.prototype.$router = this.$options.router
}
})
- 如何触发更新
hash 模式下:
- 通过 localtion.hash 修改 hash 的值,触发更新
- 通过监听 haschange 事件监听浏览器前进后退,触发更新
history 模式下:
- 通过 history.pushState 修改浏览器地址触发更新
- 通过监听 popState 事件监听浏览器前进或者后退,触发更新
如何渲染 router-view 组件?
- 通过 Vue.observable 在 router 实例上创建一个保存当前路由的监控对象 current;
- 当浏览器地址变化时,修改监控 current
- 在 router-view 组件中监听监控对象 current 的变化,当 current 变化后,获取用户注册的 component,并利用 h 函数将 component 渲染 vnodes,进而更新页面视图