我們都知道單頁應(yīng)用的路由有兩種模式:hash 和 history,那么它們的工作原理是是什么?
瀏覽器提供的路由跳轉(zhuǎn)API:location與history
location與history都是瀏覽器的對象:window.location與window.history。
window.location對象
通過改變其屬性值修改頁面的 url。我們在單頁應(yīng)用中需要做到的是改變 url 不刷新頁面。
- location.href:可以改變hash值而不刷新頁面;
- location.hash:可以改變hash值而不刷新頁面;
- location.search:會刷新頁面,改變的是?后面部分;
- location.pathname:會刷新頁面,改變的域名部分;
window.history對象
history 接口是 HTML5 新增的,它有兩個方法可以改變 url 而不刷新頁面。
- history.pushState(state,title,url)
- history.replaceState():方法的參數(shù)同上,區(qū)別說它修改瀏覽器歷史中當(dāng)前歷史記錄。
url變化監(jiān)聽
當(dāng)路由發(fā)生變化的時候我們需要得知這個變化并且調(diào)用相應(yīng)的功能模塊,那么這個變化是如何被監(jiān)聽到的呢?事實(shí)上是通過瀏覽器的兩個事件來做到的。
- hashchange事件能監(jiān)聽 url hash 的改變;
- popstate事件能監(jiān)聽除 history.pushState() 和 history.replaceState() 外 url 的變化;
// hash模式
window.addEventListener("hashchange", function(e) {
console.log(e);
});
// history模式
window.addEventListener("popchange", function(e) {
console.log(e);
});
hash 模式和 history 模式的選擇
history模式:前端的url必須和實(shí)際向后端發(fā)起請求的url 一致。
hash模式對SEO不友好。
- 在 hash 模式時不使用 history.pushState() 和 history.replaceState() 方法,就只需要在 hashchange 事件回調(diào)里編寫 url 改變時的邏輯就行了;
- 而 history 模式下,我們不僅要在 popstate 事件回調(diào)里處理 url 的變化,還需要分別在 history.pushState() 和 history.replaceState() 方法里處理 url 的變化。而且 history 模式還需要后端的配合,不然用戶刷新頁面就只有 404 可以看了;
Vue中路由模式的配置
export default new Router({
mode: 'hash', // 或者h(yuǎn)istory
routes: [
{
path: '/',
name: 'home',
component: Home
}
])