欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解vue 單頁應用(spa)前端路由實現(xiàn)原理

 更新時間:2018年04月04日 09:15:40   作者:nightZing  
這篇文章主要介紹了詳解vue 單頁應用(spa)前端路由實現(xiàn)原理,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

寫在前面:通常 SPA 中前端路由有2種實現(xiàn)方式:

  1. window.history
  2. location.hash

下面就來介紹下這兩種方式具體怎么實現(xiàn)的

一.history

1.history基本介紹

window.history 對象包含瀏覽器的歷史,window.history 對象在編寫時可不使用 window 這個前綴。history是實現(xiàn)SPA前端路由是一種主流方法,它有幾個原始方法:

  1. history.back() - 與在瀏覽器點擊后退按鈕相同
  2. history.forward() - 與在瀏覽器中點擊按鈕向前相同
  3. history.go(n) - 接受一個整數(shù)作為參數(shù),移動到該整數(shù)指定的頁面,比如go(1)相當于forward(),go(-1)相當于back(),go(0)相當于刷新當前頁面
  4. 如果移動的位置超出了訪問歷史的邊界,以上三個方法并不報錯,而是靜默失敗

在HTML5,history對象提出了 pushState() 方法和 replaceState() 方法,這兩個方法可以用來向歷史棧中添加數(shù)據(jù),就好像 url 變化了一樣(過去只有 url 變化歷史棧才會變化),這樣就可以很好的模擬瀏覽歷史和前進后退了,現(xiàn)在的前端路由也是基于這個原理實現(xiàn)的。

2.history.pushState

pushState(stateObj, title, url) 方法向歷史棧中寫入數(shù)據(jù),其第一個參數(shù)是要寫入的數(shù)據(jù)對象(不大于640kB),第二個參數(shù)是頁面的 title, 第三個參數(shù)是 url (相對路徑)。

  1. stateObj :一個與指定網(wǎng)址相關的狀態(tài)對象,popstate事件觸發(fā)時,該對象會傳入回調函數(shù)。如果不需要這個對象,此處可以填null。
  2. title:新頁面的標題,但是所有瀏覽器目前都忽略這個值,因此這里可以填null。
  3. url:新的網(wǎng)址,必須與當前頁面處在同一個域。瀏覽器的地址欄將顯示這個網(wǎng)址。

關于pushState,有幾個值得注意的地方:

pushState方法不會觸發(fā)頁面刷新,只是導致history對象發(fā)生變化,地址欄會有反應,只有當觸發(fā)前進后退等事件(back()和forward()等)時瀏覽器才會刷新

這里的 url 是受到同源策略限制的,防止惡意腳本模仿其他網(wǎng)站 url 用來欺騙用戶,所以當違背同源策略時將會報錯

3.history.replaceState

replaceState(stateObj, title, url) 和pushState的區(qū)別就在于它不是寫入而是替換修改瀏覽歷史中當前紀錄,其余和 pushState一模一樣

4.popstate事件

定義:每當同一個文檔的瀏覽歷史(即history對象)出現(xiàn)變化時,就會觸發(fā)popstate事件。

注意:僅僅調用pushState方法或replaceState方法 ,并不會觸發(fā)該事件,只有用戶點擊瀏覽器倒退按鈕和前進按鈕,或者使用JavaScript調用back、forward、go方法時才會觸發(fā)。另外,該事件只針對同一個文檔,如果瀏覽歷史的切換,導致加載不同的文檔,該事件也不會觸發(fā)。

用法:使用的時候,可以為popstate事件指定回調函數(shù)。這個回調函數(shù)的參數(shù)是一個event事件對象,它的state屬性指向pushState和replaceState方法為當前URL所提供的狀態(tài)對象(即這兩個方法的第一個參數(shù))。

5.history實現(xiàn)spa前端路由代碼

<a class="api a">a.html</a>
<a class="api b">b.html</a>
 // 注冊路由
 document.querySelectorAll('.api').forEach(item => {
  item.addEventListener('click', e => {
  e.preventDefault();
  let link = item.textContent;
  if (!!(window.history && history.pushState)) {
   // 支持History API
   window.history.pushState({name: 'api'}, link, link);
  } else {
   // 不支持,可使用一些Polyfill庫來實現(xiàn)
  }
  }, false)
 });

 // 監(jiān)聽路由
 window.addEventListener('popstate', e => {
  console.log({
  location: location.href,
  state: e.state
  })
 }, false)

popstate監(jiān)聽函數(shù)里打印的e.state便是history.pushState()里傳入的第一個參數(shù),在這里即為{name: 'api'}

二.Hash

1.Hash基本介紹

url 中可以帶有一個 hash http://localhost:9000/#/a.html

window 對象中有一個事件是 onhashchange,以下幾種情況都會觸發(fā)這個事件:

  1. 直接更改瀏覽器地址,在最后面增加或改變#hash;
  2. 通過改變location.href或location.hash的值;
  3. 通過觸發(fā)點擊帶錨點的鏈接;
  4. 瀏覽器前進后退可能導致hash的變化,前提是兩個網(wǎng)頁地址中的hash值不同。

2.Hash實現(xiàn)spa前端路由代碼

 // 注冊路由
 document.querySelectorAll('.api').forEach(item => {
  item.addEventListener('click', e => {
  e.preventDefault();
  let link = item.textContent;
  location.hash = link;
  }, false)
 });

 // 監(jiān)聽路由
 window.addEventListener('hashchange', e => {
  console.log({
  location: location.href,
  hash: location.hash
  })
 }, false)

hash模式與history模式,這兩種模式都是通過瀏覽器接口實現(xiàn)的,除此之外vue-router還為非瀏覽器環(huán)境準備了一個abstract模式,其原理為用一個數(shù)組stack模擬出瀏覽器歷史記錄棧的功能。當然,以上只是一些核心邏輯,為保證系統(tǒng)的魯棒性源碼中還有大量的輔助邏輯,也很值得學習。

三、兩種模式比較

  • pushState設置的新URL可以是與當前URL同源的任意URL;而hash只可修改#后面的部分,故只可設置與當前同文檔的URL
  • pushState設置的新URL可以與當前URL一模一樣,這樣也會把記錄添加到棧中;而hash設置的新值必須與原來不一樣才會觸發(fā)記錄添加到棧中
  • pushState通過stateObject可以添加任意類型的數(shù)據(jù)到記錄中;而hash只可添加短字符串
  • pushState可額外設置title屬性供后續(xù)使用

四、history模式的一個問題

我們知道對于單頁應用來講,理想的使用場景是僅在進入應用時加載index.html,后續(xù)在的網(wǎng)絡操作通過Ajax完成,不會根據(jù)URL重新請求頁面,但是難免遇到特殊情況,比如用戶直接在地址欄中輸入并回車,瀏覽器重啟重新加載應用等。
hash模式僅改變hash部分的內容,而hash部分是不會包含在HTTP請求中的:

http://oursite.com/#/user/id // 如重新請求只會發(fā)送http://oursite.com/

故在hash模式下遇到根據(jù)URL請求頁面的情況不會有問題。

而history模式則會將URL修改得就和正常請求后端的URL一樣

http://oursite.com/user/id

在此情況下重新向后端發(fā)送請求,如后端沒有配置對應/user/id的路由處理,則會返回404錯誤。

官方推薦的解決辦法是在服務端增加一個覆蓋所有情況的候選資源:如果 URL 匹配不到任何靜態(tài)資源,則應該返回同一個 index.html 頁面,這個頁面就是你 app 依賴的頁面。同時這么做以后,服務器就不再返回 404 錯誤頁面,因為對于所有路徑都會返回 index.html 文件。為了避免這種情況,在 Vue 應用里面覆蓋所有的路由情況,然后在給出一個 404 頁面?;蛘撸绻怯?Node.js 作后臺,可以使用服務端的路由來匹配 URL,當沒有匹配到路由的時候返回 404,從而實現(xiàn) fallback。

參考資料:

1、瀏覽器History API :https://developer.mozilla.org/zh-CN/docs/Web/API/History_API

2、解決History模式訪問404的方案:https://router.vuejs.org/zh/guide/essentials/history-mode.html#%E5%90%8E%E7%AB%AF%E9%85%8D%E7%BD%AE%E4%BE%8B%E5%AD%90

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • vue中使用svg封裝全局消息提示組件

    vue中使用svg封裝全局消息提示組件

    這篇文章主要為大家詳細介紹了vue中使用svg封裝全局消息提示組件,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • VUE簽字組件vue-esign安裝使用教程

    VUE簽字組件vue-esign安裝使用教程

    在我們開發(fā)項目中,特別是流程審批類的項目,最后一步會提交審核,審核員看完相應信息以后,沒問題就會簽字通過審批,這篇文章主要給大家介紹了關于VUE簽字組件vue-esign安裝使用的相關資料,需要的朋友可以參考下
    2023-09-09
  • vue3 setup中defineEmits與defineProps的使用案例詳解

    vue3 setup中defineEmits與defineProps的使用案例詳解

    在父組件中定義String、Number、Boolean、Array、Object、Date、Function、Symbol這些類型的數(shù)據(jù),使用defineEmits會返回一個方法,使用一個變量emits(變量名隨意)去接收,本文給大家介紹vue3 setup中defineEmits與defineProps的使用案例,感興趣的朋友一起看看吧
    2023-10-10
  • element-ui?el-table表格固定表頭代碼示例

    element-ui?el-table表格固定表頭代碼示例

    Element-UI的el-table組件是一個非常強大的表格組件,它提供了多種常見的表格功能,如排序、篩選、分頁、自定義列模板等,這篇文章主要給大家介紹了關于element-ui?el-table表格固定表頭的相關資料,需要的朋友可以參考下
    2024-05-05
  • vue3路由router.push的使用以及問題分析

    vue3路由router.push的使用以及問題分析

    頁面跳轉有很多方法,本次使用的是?vue-router,但卻在使用?router.push?的時候遇到了點麻煩,所以記錄下來,希望可以幫助有需要的人
    2023-09-09
  • Vue3中的組合式?API示例詳解

    Vue3中的組合式?API示例詳解

    組合式 API 是一系列 API 的集合,使我們可以使用函數(shù)而不是聲明選項的方式書寫 Vue 組件,這篇文章主要介紹了什么是Vue3的組合式?API,需要的朋友可以參考下
    2022-06-06
  • 基于element-ui中el-select下拉框選項過多的優(yōu)化方案

    基于element-ui中el-select下拉框選項過多的優(yōu)化方案

    這篇文章主要介紹了基于element-ui中el-select下拉框選項過多的優(yōu)化方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • 關于Vue不能監(jiān)聽(watch)數(shù)組變化的解決方法

    關于Vue不能監(jiān)聽(watch)數(shù)組變化的解決方法

    本文主要介紹了Vue不能監(jiān)聽(watch)數(shù)組變化的解決方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • 程序員應該知道的vuex冷門小技巧(超好用)

    程序員應該知道的vuex冷門小技巧(超好用)

    Vue基本用法很容易上手,但是有很多優(yōu)化的寫法你就不一定知道了,下面這篇文章主要給大家介紹了關于程序員應該知道的vuex冷門小技巧的相關資料,需要的朋友可以參考下
    2022-05-05
  • Vue實現(xiàn)二維碼的展示及下載功能

    Vue實現(xiàn)二維碼的展示及下載功能

    這篇文章主要介紹了Vue實現(xiàn)二維碼的展示及下載功能,其中downloadQRCode()函數(shù)中的url為要下載的文件的路徑,本文通過實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-05-05

最新評論