路由基本配置
1.在router文件夾中找到 indexs.js
注意:如果創建項目是沒有安裝router,不會有router文件夾,該文件夾在src 文件夾的根目錄中
// 1.引入路由以及vue,下面的是固定寫法,照寫就可以
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
2.創建路由實例
const router = new Router({
linkActiveClass: 'app-active', // 路由點擊選中時的顏色(app-active爲自定義的class樣式類)
routes: [
{ // 根路徑
path: '/',
redirect: '/home',
component: () => import('@/pages/home') // 路由懶加載寫法
},
{
path: '/home',
name: 'home',
component: () => import('@/pages/home'),
}
})
/* 路由攔截器 路由跳轉前的操作 */
router.beforeEach((to, from, next) => {
next()
})
/* 路由攔截器 路由跳轉後的操作 */
router.afterEach(to => {
})
3.將路由導出,供外部接收,主要用於main.js接收
export default router
2.配置好router中的index.js文件後需要在main.js 中,掛載路由router到vue實例上
import Vue from 'vue'
import App from './App'
import router from './router' // 導入配置好的路由文件
import store from './store' // 導入配置好的vuex文件
Vue.config.productionTip = false
new Vue({
el: '#app',
router, // 掛載路由到實例中
store,// 掛載vuex到實例中
components: { App },
template: '<App/>'
})
通過上面兩步,路由的基本配置已經完成可以正常使用路由了。
路由元信息meta使用
1.路由攔截器
router.beforeEach( to, from, next )
router.afterEach( to, from )
參數說明:
to:表示要跳轉的路由對象。
from:表示跳轉前的路由對象
next:繼續執行跳轉的函數,只有跳轉前的攔截纔有這個參數。
import Router from 'vue-router'
Vue.use(Router)
const router = new Router({
routes: [{
path: '/',
redirect: '/home',
component: () => import('@/pages/home')
}]
})
/* 路由攔截器 路由跳轉前的操作 */
router.beforeEach((to, from, next) => {
/* 路由跳轉前可進行各種操作,如數據處理,權限驗證,取消上頁所有網絡請求等等,
*一定要注意,數據處理後,一定要執行next(),否則路由不會進行跳轉。*/
if(true){
// 進行的操作
next()
}else{
// 進行的一些操作
next()
}
})
/* 路由攔截器 路由跳轉後的操作 */
router.afterEach(to => {
// 在這裏執行路由跳轉成功後所進行的操作
})
export default router
上面已經解了攔截器的基本使用,下面再來看一下,攔截器結合路由元信息meta的使用。
2.路由攔截器中元信息meta對象的使用----登陸攔截驗證 和 修改頁面的 title
場景描述如下圖:
1.用戶訪問home頁面,或者home的子頁面mine頁面時,由於home只有登陸後才能進入,所以用戶在訪問這兩個頁面時需要判斷是否登錄,如果沒有登錄就跳轉到登錄頁面,登錄成功後自動跳轉到用戶訪問的權限頁面。
2.當調轉對應的路由頁面時,就更改網頁的名字,也就是index.heml 中 head 標籤裏面的 title 的值
(1)、首先準備三個路由頁面,home.vue 、 login.vue 、mine.vue
/*------------------------------------------home.vue------------------------------------------*/
<template>
<div>
<h1>首頁</h1>
<router-link to="/home/mine">前往首頁子頁面</router-link>
<router-view></router-view>
<div>
</template>
...
/*------------------------------------------mine.vue------------------------------------------*/
<template>
<div>
<h1>子頁面</h1>
<div>
</template>
...
/*------------------------------------------login.vue------------------------------------------*/
<template>
<div>
<h1>登錄頁面</h1>button
<button @click="login">前往首頁子頁面</button>
<div>
</template>
<script>
...
methodes:{
login(){
localStorage.login = true // 登錄狀態
// this.$route.params.redirect 是路由攔截是傳過來的攔截頁面的路由對象,看下文的路由攔截配置詳情,有說明。
if( this.$route.params.redirect ){ // 判斷是否有redirect參數
this.$router.push( this.$route.params.redirect ) 登錄後跳回被的攔截
}
}
}
...
</script>
(2)、在路由配置router/index.js文件中 設置路由攔截
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
const router = new Router({
routes: [
{ // 根路徑
path: '/',
redirect: '/home',
component: () => import('@/pages/home'), // 路由懶加載寫法
},{
path: '/home',
name: 'home',
component: () => import('@/pages/home'),
meta:{
isLogin : true // 自定義一個屬性,true需要登錄權限
title:"主頁"
},
children:[{
path: 'mine',
name: 'mine',
component: () => import('@/pages/home/mine'),
meta:{ // 不做登錄權限的設置
title:"用戶中心頁"
}
}]
},{
path: '/login',
name: 'login',
component: () => import('@/pages/login'),
meta:{
title:"登錄頁"
}
},
})
//導航前守衛(跳轉前)
router.beforeEach(function(to,from,next){
// to: 表示要跳轉的頁面。from:表示從哪個頁面來
let login_in = localStorage.login // 是否已登錄
let require = to.matched.some(function(item){ // 是否需要登錄
return item.meta.isLogin
})
if( !login_in && require ){ // 當未登錄,且跳轉的頁面需要登錄後才能操作時,進行路由攔截
next({ // 跳轉登錄頁
name: "login",
params: { redirect: to } // 將 要跳轉(即被攔截) 的路由對象,作爲參數,傳遞到登錄頁面
});
}else{ // 已登錄就正常跳轉,不做任何攔截
next() // 正常跳轉到下一頁
}
})
//導航後守衛(跳轉後)
router.afterEach(function(to,from){
document.title = to.meta.title //跳轉後設置頁面的title
})
export default router
到此所需的功能我們已經實現了。
細心的人可能會發現 beforeEach 攔截器中 變量 require 的值不是應該直接用路由meta.isLogin 的值 即 to.meta.isLogin的值?。爲什麼使用了數組some()方法對to.matched進行循環,來賦值?to.matched又指的是什麼?
這一步很重要,不能直接使用to.meta.isLogin的值,這樣的話只是跳轉到home.vue時會被攔截,但是如果直接在地址欄訪問 home.vue 的子頁面mine.vue時如:localhost:8080/#/home/mine ,就不會進行攔截。
因爲mine.vue頁面,配置路由時沒有在meta中設置 isLogin,所以to.meta.isLogin的值是false,會直接跳轉不會進行攔截。所以要循環to.matched 進行判斷。說了這麼多,咱來看一下to.matched指的是什麼:
to.matched 返回的是一個數組,裏面是存放的是路由對象,指當前匹配的路徑中所包含的路由片段所對應的路由對象。
比如:localhost:8080/#/home/mine 這個路徑中我看到有兩個路由片段home 和 mine
因此to.matched 的數組存放的就是 home 和 mine 的路由實例。用數組some()循環方法,是匹配數組中所有元素,只要有一個元素的某個值到達了條件 item.meta.isLogin 爲true,該方法就會返回true。所以直接訪問mine頁面時,to.matched數組中,home對象的meta.isLogin是true,達到了條件,所以整體返回了true,此時 require 的值即爲true。 不懂數組some()方法的可以去惡補一下ES6-數組新增的方法。