安裝
vue add router
vue-router 的兩種模式
一被因、hash模式
后面的hash值變化,并不會導致瀏覽器向服務器發(fā)出請求,瀏覽器不發(fā)出請求也就不會刷新
頁面事富,每次hash值變化,會觸發(fā)hashchange這個事件乘陪,通過這個事件我們就可以知道hash值
發(fā)生了什么變化统台,然后通過監(jiān)聽hashchange來實現(xiàn)更新頁面部分內容的操作。
window.onhashchange = function(event){
console.log(event.oldURL, event.newURL);
let hash = location.hash.slice(1);
document.body.style.color = hash;
}
二啡邑、history模式
pushState() 和 replaceState()贱勃。通過這兩個 API
(1)可以改變 url 地址且不會發(fā)送請求,
(2)不僅可以讀取歷史記錄棧谤逼,還可以對瀏覽器歷史記錄棧進行修改贵扰。
除此之外,還有popState().當瀏覽器跳轉到新的狀態(tài)時流部,將觸發(fā)popState事件.
區(qū)別:
前面的hashchange戚绕,你只能改變#后面的url片段。而pushState設置的新URL可以是與當前URL同源的任意URL枝冀。
history模式則會將URL修改得就和正常請求后端的URL一樣,如后端沒有配置對應/user/id的路由處理舞丛,則會返回404錯誤
當用戶刷新頁面之類的操作時,瀏覽器會給服務器發(fā)送請求宾茂,所以這個實現(xiàn)需要服務器的支持瓷马,需要把所有路由都重定向到根頁面
route的區(qū)別
route.query或者 this.$route.params 接收)
router.push方法怀骤;返回上一個history也是使用$router.go方法
vue-router的構子函數(shù)
模塊一:全局導航鉤子函數(shù)
1费封、vue router.beforeEach(全局前置守衛(wèi))
beforeEach的鉤子函數(shù),它是一個全局的before 鉤子函數(shù)蒋伦, (before each)意思是在 每次每一個路由改變的時候都得執(zhí)行一遍弓摘。
2、vue router.afterEach(全局后置守衛(wèi))
router.beforeEach 是頁面加載之前痕届,相反router.afterEach是頁面加載之后
它的三個參數(shù):
to: (Route路由對象) 即將要進入的目標 路由對象 to對象下面的屬性: path params query hash fullPath matched name meta(在matched下韧献,但是本例可以直接用)
from: (Route路由對象) 當前導航正要離開的路由
next: (Function函數(shù)) 一定要調用該方法來 resolve 這個鉤子。 調用方法:next(參數(shù)或者空) ***必須調用
next(無參數(shù)的時候): 進行管道中的下一個鉤子研叫,如果走到最后一個鉤子函數(shù)锤窑,那么 導航的狀態(tài)就是 confirmed (確認的)
next('/') 或者 next({ path: '/' }): 跳轉到一個不同的地址。當前的導航被中斷嚷炉,然后進行一個新的導航渊啰。
應用場景:可進行一些頁面跳轉前處理,例如判斷需要登錄的頁面進行攔截申屹,做登錄跳轉;嬷ぁ!
router.beforeEach((to, from, next) => {
if (to.meta.requireAuth) {
//判斷該路由是否需要登錄權限
if (cookies('token')) {
//通過封裝好的cookies讀取token哗讥,如果存在嚷那,name接下一步如果不存在,那跳轉回登錄頁
next()//不要在next里面加"path:/",會陷入死循環(huán)
}
else {
next({
path: '/login',
query: {redirect: to.fullPath}//將跳轉的路由path作為參數(shù)杆煞,登錄成功后跳轉到該路由
})
}
}
else {
next()
}
})
應用場景车酣,進入頁面登錄判斷、管理員權限判斷索绪、瀏覽器判斷
//使用鉤子函數(shù)對路由進行權限跳轉
router.beforeEach((to, from, next) => {
const role = localStorage.getItem('ms_username');
if(!role && to.path !== '/login'){
next('/login');
}else if(to.meta.permission){
// 如果是管理員權限則可進入,這里只是簡單的模擬管理員權限而已
role === 'admin' ? next() : next('/403');
}else{
// 簡單的判斷IE10及以下不進入富文本編輯器贫悄,該組件不兼容
if(navigator.userAgent.indexOf('MSIE') > -1 && to.path === '/editor'){
Vue.prototype.$alert('vue-quill-editor組件不兼容IE10及以下瀏覽器瑞驱,請使用更高版本的瀏覽器查看', '瀏覽器不兼容通知', {
confirmButtonText: '確定'
});
}else{
next();
}
}
})
模塊二:路由獨享的守衛(wèi)(路由內鉤子)
你可以在路由配置上直接定義 beforeEnter 守衛(wèi):
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
模塊三:組件內的守衛(wèi)(組件內鉤子)
1、beforeRouteEnter窄坦、beforeRouteUpdate唤反、beforeRouteLeave
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染該組件的對應路由被 confirm 前調用
// 不!能鸭津!獲取組件實例 `this`
// 因為當鉤子執(zhí)行前彤侍,組件實例還沒被創(chuàng)建
},
beforeRouteUpdate (to, from, next) {
// 在當前路由改變,但是該組件被復用時調用
// 舉例來說逆趋,對于一個帶有動態(tài)參數(shù)的路徑 /foo/:id盏阶,在 /foo/1 和 /foo/2 之間跳轉的時候,
// 由于會渲染同樣的 Foo 組件闻书,因此組件實例會被復用名斟。而這個鉤子就會在這個情況下被調用脑慧。
// 可以訪問組件實例 `this`
},
beforeRouteLeave (to, from, next) {
// 導航離開該組件的對應路由時調用
// 可以訪問組件實例 `this`
}
- 路由鉤子在實際開發(fā)中的應用場景
(一) 清除當前組件中的定時器
當一個組件中有一個定時器時, 在路由進行切換的時候, 可使用beforeRouteLeave將定時器進行清除, 以免占用內存:
beforeRouteLeave (to, from, next) {
window.clearInterval(this.timer) //清除定時器
next()
}
(二) 當頁面中有未關閉的窗口, 或未保存的內容時, 阻止頁面跳轉
如果頁面內有重要的信息需要用戶保存后才能進行跳轉, 或者有彈出框的情況. 應該阻止用戶跳轉,結合vuex狀態(tài)管理(dialogVisibility是否有保存)
beforeRouteLeave (to, from, next) {
//判斷是否彈出框的狀態(tài)和保存信息與否
if (this.dialogVisibility === true) {
this.dialogVisibility = false //關閉彈出框
next(false) //回到當前頁面, 阻止頁面跳轉
}else if(this.saveMessage === false) {
alert('請保存信息后退出!') //彈出警告
next(false) //回到當前頁面, 阻止頁面跳轉
}else {
next() //否則允許跳轉
}
(三) 保存相關內容到Vuex中或Session中
當用戶需要關閉頁面時, 可以將公用的信息保存到session或Vuex中
beforeRouteLeave (to, from, next) {
localStorage.setItem(name, content); //保存到localStorage中
next()
}