Vue 路由知識點歸納總結

下小朋友發表於2019-04-09

最近做專案才發現,我確實對 vue-router 太不熟悉了,都只瞭解個簡單用法就開始搞了,本來很簡單的問題,都搞不清楚。現在重新看一遍文件,重新梳理一下。

vue 路由的原理

說實話,路由我一直也就光顧著用,沒認真思考過這個問題,還是那次人家面試問了這個,我才反應過來是應該好好的瞭解一下了。

無重新整理跳轉頁面,是單頁應用的一大優勢,使用者體驗好,載入速度快,vue 路由的跳轉就是無重新整理的,它有兩種形式,可以在定義路由的時候通過 mode 欄位去配置,如果不配置這個欄位,那麼預設使用的就是 hash 模式。 hash 模式,即通過在連結後新增 # + 路由名字,根據匹配這個欄位的變化,觸發 hashchange 事件,動態的渲染出頁面。就有點類似像 a 連結用作頁面上的錨點一樣,不會重新整理頁面。

另外一種方式,是 history 模式,也就是使用的瀏覽器的 history API,pushStatereplaceState。通過呼叫 pushState 操作瀏覽器的 history 物件,改變當前地址,同時結合window.onpopstate 監聽瀏覽器的返回和前進事件,同樣可以實現無重新整理的跳轉頁面。replaceStatepushStete 不同的就是,前者是替換一條記錄,後者是新增一條記錄。

有關於 pushState 的用法,詳見MDN 文件。這個 API 與 ajax 合起來構成的 pjax 技術,也是用於實現頁面無重新整理載入的一種方式,常用於 PC 長列表頁面的翻頁啥的~ history 相對於 hash 模式來說,最大的好處就是沒有討厭的 # 符號,比如同樣一個 list 頁面,在 hash 模式下,url 連結表現為 http://yoursite.com/#/list,看著就難受。在 history 模式下面,url 連結表現為 http://yoursite.com/list ,看著比較清爽~而且~相信做過微信公眾號開發的都懂,這個該死的 # 有多煩人~在下面的應用場景裡面我再講下這個問題~

那麼問題來了,既然 history 模式樣子好看,功能也一樣,為啥還是用 hash 模式的人比較多【此處沒有真憑實據,我瞎說的】?因為 history 模式,還需要服務端進行配置,否則重新整理頁面就會產生 404 錯誤。這裡也比較好理解啦,因為我們實際上是使用的 pushState 操作頁面的跳轉,而不是真的去伺服器請求另外一個 list.html 檔案,那按照 http://yoursite.com/#/list 這個路徑,自然找不到啦~

如果是 nginx 的伺服器,在 location / 裡面加上 try_files $uri $uri/ /index.html; 即可。這行程式碼表示:如果匹配不到靜態資源的路徑,就將重定向到 index 頁面,這樣就不會出錯啦~因為需要找後端小哥哥修改伺服器配置檔案,如果自己沒有完全理解,兩邊又溝通不清楚的情況下,使用 history 模式的難度無疑就大了一些~不過也不是什麼大問題~全看個人需要啦哈哈~

vue 路由傳參的兩種方式

頁面引數無非就兩種,query 和 params,params 是以 /params 的形式表現在 url 上,而 query 是以 ?query=query1 這種形式表現在 url 上,此外,使用 params 引數還需要配置到路由定義上,不然不會展示在 url 上,並且重新整理就會消失。

這個比較簡單,需要注意的地方就是:如果傳 params 引數,不能使用 path 欄位跳轉,否則沒效果。而 query 引數則沒有這個限制,使用 namepath 欄位都可以。 這個雖然簡單!但是一定要自己操作一遍才記得住啊。。反正我是早就看到,但是一直記混了~~重新用 demo 寫了一遍才記住~而且別人說的也不一定就是對的,還是要自己實驗一遍才知道呢。╮(╯▽╰)╭

vue 路由的跳轉

vue 路由的跳轉分成兩種,一種是宣告式,使用<router-link>宣告跳轉,to屬性定義跳轉的引數。另一種是程式設計式,使用 router.go()router.push()router.replace()方法進行跳轉,go方法就是與瀏覽器的history api 的方法相同,可以進行返回上一頁等操作。

push方法和replace方法的區別在於,前者會把當前頁面加入 history 記錄裡面,可以通過history.go(-1)回到這個頁面。而replace方法則會在 history 記錄裡面替換掉當前記錄,如果你在跳轉後的新頁面返回上一頁,它不會回到跳轉前的頁面,會回到上上個頁面,如果上上個頁面沒有記錄,則不會跳轉。

vue 路由守衛

vue 路由守衛分為三種,一種是全域性的路由守衛,通常在例項化路由之後設定,來做一些通用的路由操作,它所有的路由跳轉都會執行的操作;一種是單個路由獨享的守衛,在單個路由定義的時候進行設定,所有跳轉這個路由都會執行;另外一種就是元件內的守衛,只在元件內生效。

全域性路由守衛型別:

  • router.beforeEach(to, from, next)
  • router.afterEach(to, from, next)

路由獨享的守衛:

  • beforeEnter(to, from, next)

元件獨享的守衛:

  • beforeRouteEnter(to, from, next)
  • beforeRouteUpdate(to, from, next) —— 動態引數路徑改變時,元件例項被複用的時候呼叫。
  • beforeRouteLeave(to, from, next) —— 導航離開元件所在路由時被呼叫。

vue 路由的一些應用場景處理

什麼時候用 push,什麼時候用 replace

最開始路由跳轉我都是用 push() 比較多,或者用 go() 做返回,很少用到過 replace() ,後來在業務需求下翻文件才發現這個漏掉的 API。簡單來說,當你需要從A頁面跳轉到B頁面,再跳轉到C頁面,然後在C頁面返回,能直接返回到A頁面。那麼在B頁面跳轉C頁面的時候,使用replace()方法進行跳轉即可。

動態改變頁面的 title

  • 定義路由的時候,在路由的 meta 欄位裡面新增一個 title 屬性,定義好頁面的標題名稱。
  • 在全域性的路由守衛beforeEach()方法裡面新增一個判斷,獲取路由的 meta 欄位,動態的改變頁面的 title。
// router.js
{
	path: '/index',
	name: 'index',
	meta: {
		title: '首頁'
	}
}

// main.js
router.beforeEach(to, from, next){
	if(to.meta.title){
		document.title = to.meta.title
	}
	next()  // 這個方法必須呼叫 不然路由不會跳轉
}
複製程式碼

微信開發,單頁應用頁面 url 導致的傳參或者跳轉失敗的問題

微信授權跳轉

在做微信授權跳轉的時候,hash 模式下連結裡面帶有 # 號可能會導致重定向跳轉失敗,使用 encodeURIComponent 把頁面地址處理之後,再傳入。

let _url = encodeURIComponent(location.href)
location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${this.appid}&redirect_uri=${_url}&response_type=code&scope=snsapi_base&state=#wechat_redirect`
複製程式碼

獲取 wxconfig 配置

前端獲取 wxconfig 比較簡單,主要的操作都在後端,前端只需要傳一個 url 引數,由後端去獲取 config 的引數,回傳給前端。前端拿到引數後,呼叫 wx.config 方法。

let url = location.href.split('#')[0]
http.get('weixin/config',{
    params:{
        url: encodeURIComponent(url)
    }
})
.then(res=>{
    wx.config({
        beta: true,        // 必須這麼寫,否則wx.invoke呼叫形式的jsapi會有問題
        debug: false,                       // 開啟除錯模式,呼叫的所有api的返回值會在客戶端alert出來,若要檢視傳入的引數,可以在pc端開啟,引數資訊會通過log打出,僅在pc端時才會列印。
        appId: res.data.appId,           // 必填,企業微信的corpID
        timestamp: res.data.timestamp,  // 必填,生成簽名的時間戳
        nonceStr: res.data.nonceStr,   // 必填,生成簽名的隨機串
        signature: res.data.signature,// 必填,簽名,見 附錄-JS-SDK使用許可權簽名演算法
        jsApiList: ['scanQRCode'] // 必填,需要使用的JS介面列表,凡是要呼叫的介面都需要傳進來
    })
    // 檢測微信
    wx.error(function(res){
        //  config資訊驗證失敗會執行error函式,如簽名過期導致驗證失敗,具體錯誤資訊可以開啟config的debug模式檢視,也可以在返回的res引數中檢視,對於SPA可以在這裡更新簽名。
        console.log('錯誤資訊====',res)
    })
})
複製程式碼

單頁面應用加百度統計

在單頁應用上面,如果直接把百度統計的程式碼加到 html 不做任何處理的話,是統計不到每個頁面的訪問量的,所以把新增 js 和 監聽跳轉頁面的程式碼都寫到 main.js 裡面去。

// 新增百度統計 先判斷是生產環境還是開發環境 如果是開發環境 不用新增
if (process.env.NODE_ENV !== 'development') {
    let _hmt = _hmt || [];
    window._hmt = _hmt;  // 必須把_hmt掛載到window下,否則找不到
    (function() {
        var hm = document.createElement("script");
        hm.src = "https://hm.baidu.com/hm.js?yourappid";
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(hm, s);
    })()
}

router.beforeEach(to, from, next){
	// 新增百度統計程式碼 先判斷是生產環境還是開發環境
    if (process.env.NODE_ENV !== 'development') {
        // 新增頁面統計
        if (_hmt) {
            if (to.path) {
                _hmt.push(['_trackPageview', '/#' + to.fullPath]);
            }
        }
    }
}
複製程式碼

參考文件: segmentfault.com/a/119000001…
www.jianshu.com/p/febd38110…

相關文章