Vue-Router的routes配置詳解
目錄
- 介紹
- routes中物件屬性
- path: string
- component : Component | () => import(元件)
- name: string
- redirect: string | Location | Function
- props: boolean | Object | Function
- alias: string| Array[string]
- children?: Array[RouteConfig]
- beforeEnter: (to: Route,from: Route,next: Function) => void
- Router的例項方法
- *Router例項屬性
- VueRouter例項方法
- router.push(string | location)
- router.replace(string | location)
- router.go(Int number)
- router.back()
- router.forward()
- 路由懶載入
- 沒有使用懶載入
- 使用懶載入
- history模式和hash模式
- history模式
- hash模式
- 路由守衛
- 全域性路由守衛
- 情況一
- 情況二
- 情況三
介紹
在使用vue-router的專案中,例項化VueRouter是其配置選項routes該選項指定路由與檢視的元件的關係或者路由與其他路由的關係,Router配置選項中是其中最重要的配置。
routes中物件屬性
interface RouteConfig = { path: string,component?: Component,name?: string,// 命名路由 *components?: { [name: string]: Component },// 命名檢視元件 https://routerhttp://www.cppcns.com.vue.org/zh/guide/essentials/named-views.html#%E5%B5%8C%E5%A5%97%E5%91%BD%E5%90%8D%E8%A7%86%E5%9B%BE redirect?: string | Location | Function,props?: boolean | Object | Function,alias?: string | Array<string>,children?: Array<RouteConfig>,// 巢狀路由 beforeEnter?: (to: Route,next: Function) => void,*meta?: any,// 2.6.0+ *caseSensitive?: boolean,// 匹配規則是否大小寫敏感?(預設值:false) *pathToRegexpOptions?: Object // 編譯正則的選項 }
path: string
指定當前路由的路徑,當瀏覽器url與path匹配時router-view就會渲染當前route物件指定檢視元件component/components
const routes = [ { path: '/',component: Home },{ path:'/user',component: User } ] const router = new VueRouter({ routes })
注意Vue的router支援動態路徑,以 "/:屬性名"形式作為當前path字串中的一部分。這段字串路由將作為動態路由匹配真實url上響應字串資訊
const routes = [ { path: '/',{ path:'/user/:id/:local',// 動態路徑 :id :local component: User } ] const router = new VueRouter({ routes,}) // 路由跳轉 <div id="app"> <router-viwww.cppcns.comew /> // 下面這些連結都會與/user/:id/:local匹配 <router-link to="/user/007/lk">使用者007</router-link> <router-link to="/user/111/js">使用者111</router-link> <router-link to="/user/10086/yk">使用者10086</router-link> <router-link to="/user/241247/la">使用者241247</router-link> </div> /* 當我們跳轉至上面的路由時其對應的路由檢視元件User內部就可以通過 this.$route.params 獲取到動態路徑匹配到的資訊 例子: url /user/007/lk this.$route.params -> {id:'007',local:'lk'} url /user/10086/yk this.$route.params -> {id:'10086',local:'yk'} */
注意this.$route就是當前vue應用程式所在路由的資訊物件
// http://localhost:8080/#/user/10086/cc?wd=iPhone&aa=test { name: undefined,// 當前路由名 *fullPath: "/user/10086/cc" // 當前url完整路徑 *hash: "" // 當前路由的雜湊 *matched: [{…}] *meta: {} params: {id: "10086",local: "cc"} // 動態路徑匹配到鍵值對物件 *path: "/user/10086/cc" // 當前url匹配到的路徑 query: { // url的query字串網址?後面的引數解析出來的物件 wd: "iPhone",aa: "test" } }
component : Component | () => import(元件)
當前瀏覽器url與路由的path匹配時所渲染的路由元件
import Vue from 'vue' import HotMusicList from '../views/HotMusicList' const routes = [ { path: '/hot',component: HotMusicList },{ // 動態路徑匹配 通過:id獲取每一首歌不同的id path: '/music/:id',// 路由的懶載入,通過函式的形式,可以讓專案中哪些不許一開始就要載入的元件,載入到專案中去 // 只有瀏覽器跳轉到當前路由時,該路由元件才會載入到專案中去 // 這樣做的好處是減少不必要的載入降低應用載入速度和執行頻寬 component: () => import('../views/MusicPlay') } ]
注意在專案開發中應用中不需要一開始就載入的路由元件請使用懶載入
name: string
給路由命名,讓路由成為具名路由。路由的導航就可以使用name進行跳轉。(路由使用location導航時只有具名路由可可以直接接受pramas傳參)
const routes = [ { path: '/user',name: 'User',component: () => import('../views/User.vue') } ]
redirect: string | Location | Function
重定向路由,當前應用訪問導航至該路由時,這個路由會(以替換的形式)自動重定向到redirect指定的新路由
const routes = [ { path: '/contact',component: ContactView },{ path: '/user/:id',component: () => import('../views/User.vue') },{ path: '/oldpath1',redirect: '/contact' },{ path: '/oldpath2',redirect: { name: 'User',params: { name: '小明',age: 19 } } },/* redirect 支援函式的形式,該函式接收一個引數就是個訪問oldpath時生成的location物件 redirect 函式的形式必須返回重定向路由的path或location */ { path: '/oldpath2',redirect:(oldpathLocation) => '/contact' } { path: '/oldpath4',redirect:(oldpathLocation) => { name: 'User',age: 19 } } } ]
props: boolean | Object | Function
路由的動態匹配一般情況下只能通過,this.$route.params獲取動態匹配到的值。當設定props屬性後動態匹配到的鍵值對可以作為元件props直接傳遞給檢視元件,這樣大大降低元件的耦合性
布林值.如果props被設定為true,route.params所有鍵值對將會被設定為元件props屬性。
const routes = [ { path: '/hot',// 路由的懶載入 component: () => import('../views/MusicPlay'),props: true } ] // 元件內部 就可通過props的id 訪問到this.$route.id <template> <div> 歌曲播放 <audio controls :src="musicUrl"/> </div> </template> <script> export default { props: ['id'],// 路由動態路徑匹配到的鍵值對會自動傳遞給當前元件的同名props data() { return { musicUrl: '' } },created() { fetch(`/song/url?id=${this.id}`) .then((res) => res.json()) .then(({ data }) => { //真實開發中這裡要判斷資料是否請求成功 console.log(data[0]); // 把歌曲的資料賦值給data this.musicUrl = data[0]?.url }); },}; </script>
物件props物件形式,就是將物件key作為渲染元件props屬性名,value就是對應屬性值 (這種寫法value不會改變所以傳遞props都是一些靜態屬性)
{ path: '/home/:id',name: 'Home',props: { a: 1,b: false },component: Home }
函式props的函式寫法接收當前路由資訊物件作為引數,該函式會返回一個物件.物件的key就是渲染元件props屬性名,value就是對應屬性值
{ path: '/home/:id',props: (route) => ({ a: route.query.wd,//將路由query.wd傳遞給元件Home的a props b: route.params.id //將路由params.id傳遞給元件Home的b props }),component: Home }
alias: string| Array[string]
路由的別名,可以給一個路由設定多個路徑。當訪問這些別名路徑時都會訪問同一個路由元件
const routes = [ { path: '/hot',component: HotMusicList,alias: ['/list','/rank','recommend'] } ]
children?: Array[RouteConfig]
巢狀路由,可以給當前路由設定二級路由
[ { path: '/home',component: Home,children: [ { path: '/home/follow',component: () => import('../views/home/Follow') },{ path: 'recommend',//路由前不加/相對路徑等價於 "/home/recommed" component: () => import('../views/home/Recommend') } ] } ]
beforeEnter: (to: Route,next: Function) => void
路由的獨享守衛,當應用將要導航到當前路由時,可以使用該守衛進行一些邏輯運算實現是否阻止本次導航
Router的例項方法
概念將VueRouter例項物件配置到Vue中後,vue例項就會擁有一個this.$router屬性,this.$router就是www.cppcns.com當前VueRouter的例項物件。他提供了所有式導航的API。
注意router是路由例項物件裡面包含著路由的屬性方法,router是路由例項物件裡面包含著路由的屬性方法,route是當前瀏覽訪問url路由信心物件
*VueRouter例項屬性
- app配置了當前router的 Vue 根例項
- mode當前Router使用的模式 "hash" | "history"
- currentRoute當前路由對應的route資訊物件
VueRouter例項方法
router.push(string | location)
程式設計式導航到指定的路由
<template> <div> <h3>主頁</h3> <div class="tab"> <router-link to="/home/follow">關注</router-link>| <button @click="gotoRecommend">推薦</button> </div> <router-view /> </div> </template> <script> export default { methods: { gotoRecommend() { // this.$router.push("/home/recommend"); this.$router.push({path:"/home/recommend",query:{wd:1,offset:0}}) },},}; </script>
router.replace(string | location)
程式設計式替換當前路由導航到新路由
<template> <div> <h3>主頁</h3> <div class="tab"> <router-link to="/home/follow">關注</router-link>| <button @click="gotoRecommend">推薦</button> </div> <router-view /> </div> </template> <script> export default { methods: { gotoRecommend() { // this.$router.replace("/home/recommend"); this.$router.replace({path:"/home/recommend",}; </script>
router.go(Int number)
程式設計式從當前路由history棧的位置前進後退number條
this.$router.go(3) // 從當前路由history棧的位置前進3條 this.$router.go(-1) // 從當前路由history棧的位置後退1條 this.$router.go(0) // 強制重新整理頁面
注意當前進/後退的number大於例項路由history棧的長度時,會前進到最後一條或後退到第一條,但是不推薦這樣做會引起效能問題造成頁面卡頓
router.back()
程式設計式從當前路由history棧的位置後退1條
this.$router.back() // 等價於this.$router.go(-1)
router.forward()
程式設計式從當前路由history棧的位置前進1條
this.$router.forward() // 等價於this.$router.go(1)
路由懶載入
用vue.js寫單頁面應用時,會出現打包後的包非常大,影響頁面載入,我們可以利用路由的懶載入去優化這個問題,當我們用到某個路由後,才去載入對應的元件,這樣就會更加高效
沒有使用懶載入
先引入了元件,事先載入好了。然後不管有沒有使用都已經存在
import Vue from 'vue' import VueRouter from 'vue-router' import Home from '../views/Home.vue' Vue.use(VueRouter) const routes = [ { path: '/',component: Home },] const router = new VueRouter({ routes }) export default router
使用懶載入
只有路由被使用到了才進行載入對應的元件
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) const routes = [ { path: '/mock',name: 'Mock',// route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ '../views/Mock.vue') } ] const router = new VueRouter({ routes }) export default router
history模式和hash模式
vue-router 預設 hash 模式 —— 使用 URL 的 hash 來模擬一個完整的 URL,於是當 URL 改變時,頁面不會重新載入。
如果不想要很醜的 hash,我們可以用路由的 history 模式,這種模式充分利用 history.pushState API 來完成 URL 跳轉而無須重新載入頁面。
history模式
history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定瀏覽器支援)這兩個方法應用於瀏覽器的歷史記錄棧,在當前已有的 back、forward、go 的基礎之上(方法可在Router的例項方法中檢視),它們提供了對歷史記錄進行修改的功能。只是當它們執行修改時,雖然改變了當前的 URL,但瀏覽器不會立即向後端傳送請求。
手動設定
效果
hash模式
hash —— 即位址列 URL 中的 # 符號(此 hash 不是密碼學裡的雜湊運算)。比如這個 URL:http://localhost:8081/#/form hash 的值為 #/form。它的特點在於:hash 雖然出現在 URL 中,但不會被包括在 HTTP 請求中,對後端完全沒有影響,因此改變 hash 不會重新載入頁面。
路由守衛
全域性路由守衛
- router.beforeEach 前置守衛
- *routerYDBcMT.beforeResolve 前置守衛
- *router.afterEach 後置守衛
情況一
在使用vue-router開發的專案中,一般情況下不同路由之間的切換會將離開的路由元件解除安裝,進入的路由元件掛載。
這種情況下我們可通過vue的宣告週期進行一些頁面的邏輯操作。但是如果有些情況下應用為提高使用者體驗減少解除安裝頻率或者儲存離開元件的活躍性,使用keep-alive元件包裹router-view後路由的切換就把會解除安裝離開的元件了。這時,如果你的元件需要在路由進入或離開時進行一些操作修改元件自身的資料DOM程式設計等,就不能再依靠vue的生命週期了。這種情況下請使用元件內的路由守衛。
- beforeRouteEnter 路由元件將要進入
- beforeRouteUpdate(2.2 新增) 路由元件將要更新 -> /music/10086 /music/10010
- beforeRouteLeave 路由元件將要離開
export default { props: ['id'],data() { return { musicUrl: '' } },beforeRouteEnter (to,from,next) { // 在渲染該元件的對應路由被 confirm 前呼叫 // 不!能!獲取元件例項 `this` // 因為當守衛執行前,元件例項還沒被建立 console.log(undefined) },beforeRouteUpdate (to,next) { // 在當前路由改變,但是該元件被複用時呼叫 // 舉例來說,對於一個帶有動態引數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候, // 由於會渲染同樣的 Foo 元件,因此元件例項會被複用。而這個鉤子就會在這個情況下被呼叫。 // 可以訪問元件例項 `this` },beforeRouteLeave (to,next) { // 導航離開該元件的對應路由時呼叫 // 可以訪問元件例項 `this` } }
注意元件獨享的路由守衛方法都包含三個引數 to from next
- to : location 本次路由導航跳轉的目標路由資訊物件
- from : location 本次路由導航從哪個路由資訊物件跳轉而來()
- next : function 該方法是否允許本次路由跳轉
next() // 允許路由跳轉 next(true) // 允許路由跳轉 next(false) // 不允許路由跳轉 next('/') / next({ path: '/' }) // 跳轉到一個不同的地址。當前的導航被中斷,然後進行一個新的導航。你可以向 next 傳遞任意位置物件,且允許設定諸如 replace: true、name: 'home' 之類的選項。 // 注意 只有beforeRouteEnter 的next方法可以接受一個回撥函式,// 該回調函式接收當前路由元件例項物件作為引數,我們可以通過該引數操作當前元件 beforeRouteEnter(to,next) { console.log(to,from) console.log('元件將要進入,這是元件例項還不存在',this) next(vm => { fetch(`/song/url?id=${vm.id}`) .then((res) => res.json()) .then(({ data }) => { //真實開發中這裡要判斷資料是否請求成功 console.log(data[0]); // 把歌曲的資料賦值給data vm.musicUrl = data[0]?.url }); }) // 允許路由跳轉 }
情況二
在使用vue-router開發的專案中,進入的路由元件掛載。
這種情況下我們可通過vue的宣告週期進行一些頁面的邏輯操作。但是如果有些情況下應用為提高使用者體驗減少解除安裝頻率或者儲存離開元件的活躍性,使用keep-alive元件包裹router-view後路由的切換就吧會解除安裝離開的元件了這時,如果你的元件需要在路由進入或離開時進行一些操作不需要修改元件自身的狀態只是判斷是否允許本次路由的跳轉等。這種情況下請使用路由獨享守衛。
beforeEnter(to,next) 當路由將要導航至當前路由時觸發 const router = new VueRouter({ routes: [ { path: '/foo',component: Foo,beforeEnter: (to,next) => { // ... } } ] })
案例 登入驗證 路由獨享守衛配置
const routes = [ { path: '/',{ path: '/discover',component: () => import('../views/Discover') },{ path: '/mine',component: () => import('../views/Mine'),//路由獨享守衛 beforeEnter(to,next) { // 因為這個守衛沒有任何DOM操作或者對元件自身狀態進行讀寫 // 這樣的守衛就可以作為路由獨享守衛 // 正確的做法存在cookie storage中 if (localStorage.getItem("user")) { next(); } else { // 這裡嗎沒有this,next接收一個回撥函式,在回撥函式中跳轉 // 下面的寫法進入了個人頁面,又從個人頁面重定向到登入,這樣可能會造成一些不必要的bug // next((vm) => { // vm.$router.replace('/landr') // }); next({name:'login',params:{to}}); //阻止本次跳轉,直接導航到指定路由 } } },{ path: '/landr',// login an register component: () => import('../views/loginanregister/LoginAndRegister'),children: [ { name:'login',path: 'login',component: () => import('../views/loginanregister/Login') },{ path: 'register',component: () => import('../views/loginanregister/Register') } ] } ]
情況三
全域性路由守衛,當應用中有多個路由都需要進行相同邏輯的路由守衛判斷時,並且該邏輯操作中不需要直接操作元件DOM或元件元件的狀態這是就可以使用全域性路由守衛(全域性守衛最常見的應用就是登陸驗證)
beforeEach(to,next) 全域性前置守衛
import Vue from 'vue' import Router from 'vue-router' import Home from '../views/Home' Vue.use(Router) const routes = [ { path: '/',name: 'Discover',name: 'Mine',children: [ { name: 'login',component: () => import('../views/loginanregister/Register') } ] } ] const router = new Router({ routes,linkExactActiveClass: 'active' }) // 路由的全域性守衛所有的路由跳轉,都會呼叫該守衛 // 全域性路由守衛也是Vue router應用中,最適合做登入驗證的地方 router.beforeEach((to,next) => { if(to.name === "Mine" || to.name === "Discover") { // 因為這個守衛沒有任何DOM操作或者對元件自身狀態進行讀寫 // 這樣的守衛就可以作為路由獨享守衛 // 正確的做法存在cookie storage中 if (localStorage.getItem("user")) { next(); } else { // 這裡嗎沒有this,在回撥函式中跳轉 // 下面的寫法進入了個人頁面,這樣可能會造成一些不必要的bug // next((vm) => { // vm.$router.replace('/landr') // }); next({ name: 'login',params: { to } }); //阻止本次跳轉,直接導航到指定路由 } }else { next() } }) export default router
router.beforeResolve(to,next) 全域性前置守衛,在beforeEach觸發之後
router.afterEach(to,from) 全域性後置守衛,該守衛路由已經離開時觸發,該守衛沒有next,next函式也不會改變導航本身
到此這篇關於Vue-Router的routes配置詳解的文章就介紹到這了,更多相關Vue-Router routes配置內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!