Vue-Router的routes配置詳解
介紹
在使用vue-router的項目中,實例化VueRouter是其配置選項routes該選項指定路由與視圖的組件的關系或者路由與其他路由的關系,Router配置選項中是其中最重要的配置。
routes中對象屬性
interface RouteConfig = { path: string, component?: Component, name?: string, // 命名路由 *components?: { [name: string]: Component }, // 命名視圖組件 https://router.vuejs.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, from: Route, next: Function) => void, *meta?: any, // 2.6.0+ *caseSensitive?: boolean, // 匹配規(guī)則是否大小寫敏感?(默認值: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支持動態(tài)路徑,以 "/:屬性名"形式作為當前path字符串中的一部分。這段字符串路由將作為動態(tài)路由匹配真實url上響應字符串信息
const routes = [ { path: '/', component: Home }, { path:'/user/:id/:local', // 動態(tài)路徑 :id :local component: User } ] const router = new VueRouter({ routes, }) // 路由跳轉(zhuǎn) <div id="app"> <router-view /> // 下面這些鏈接都會與/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> /* 當我們跳轉(zhuǎn)至上面的路由時其對應的路由視圖組件User內(nèi)部就可以通過 this.$route.params 獲取到動態(tài)路徑匹配到的信息 例子: 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"} // 動態(tài)路徑匹配到鍵值對對象 *path: "/user/10086/cc" // 當前url匹配到的路徑 query: { // url的query字符串網(wǎng)址?后面的參數(shù)解析出來的對象 wd: "iPhone", aa: "test" } }
component : Component | () => import(組件)
當前瀏覽器url與路由的path匹配時所渲染的路由組件
import Vue from 'vue' import HotMusicList from '../views/HotMusicList' const routes = [ { path: '/hot', component: HotMusicList }, { // 動態(tài)路徑匹配 通過:id獲取每一首歌不同的id path: '/music/:id', // 路由的懶加載,通過函數(shù)的形式,可以讓項目中哪些不許一開始就要加載的組件,加載到項目中去 // 只有瀏覽器跳轉(zhuǎn)到當前路由時,該路由組件才會加載到項目中去 // 這樣做的好處是減少不必要的加載降低應用加載速度和運行帶寬 component: () => import('../views/MusicPlay') } ]
注意在項目開發(fā)中應用中不需要一開始就加載的路由組件請使用懶加載
name: string
給路由命名,讓路由成為具名路由。路由的導航就可以使用name進行跳轉(zhuǎn)。(路由使用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', name: 'User', component: () => import('../views/User.vue') }, { path: '/oldpath1', redirect: '/contact' }, { path: '/oldpath2', redirect: { name: 'User', params: { name: '小明', age: 19 } } }, /* redirect 支持函數(shù)的形式,該函數(shù)接收一個參數(shù)就是個訪問oldpath時生成的location對象 redirect 函數(shù)的形式必須返回重定向路由的path或location */ { path: '/oldpath2', redirect:(oldpathLocation) => '/contact' } { path: '/oldpath4', redirect:(oldpathLocation) => { name: 'User', params: { name: '小明', age: 19 } } } ]
props: boolean | Object | Function
路由的動態(tài)匹配一般情況下只能通過,this.$route.params獲取動態(tài)匹配到的值。當設置props屬性后動態(tài)匹配到的鍵值對可以作為組件props直接傳遞給視圖組件,這樣大大降低組件的耦合性
布爾值.如果 props 被設置為 true,route.params 所有鍵值對將會被設置為組件props屬性。
const routes = [ { path: '/hot', component: HotMusicList }, { // 動態(tài)路徑匹配 通過:id獲取每一首歌不同的id path: '/music/:id', // 路由的懶加載 component: () => import('../views/MusicPlay'), props: true } ] // 組件內(nèi)部 就可通過props的id 訪問到this.$route.id <template> <div> 歌曲播放 <audio controls :src="musicUrl"/> </div> </template> <script> export default { props: ['id'], // 路由動態(tài)路徑匹配到的鍵值對會自動傳遞給當前組件的同名props data() { return { musicUrl: '' } }, created() { fetch(`/song/url?id=${this.id}`) .then((res) => res.json()) .then(({ data }) => { //真實開發(fā)中這里要判斷數(shù)據(jù)是否請求成功 console.log(data[0]); // 把歌曲的數(shù)據(jù)賦值給data this.musicUrl = data[0]?.url }); }, }; </script>
對象props對象形式,就是將對象key作為渲染組件props屬性名,value就是對應屬性值 (這種寫法value不會改變所以傳遞props都是一些靜態(tài)屬性)
{ path: '/home/:id', name: 'Home', props: { a: 1, b: false }, component: Home }
函數(shù)props的函數(shù)寫法接收當前路由信息對象作為參數(shù),該函數(shù)會返回一個對象.對象的key就是渲染組件props屬性名,value就是對應屬性值
{ path: '/home/:id', name: 'Home', 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, from: Route, next: Function) => void
路由的獨享守衛(wèi),當應用將要導航到當前路由時,可以使用該守衛(wèi)進行一些邏輯運算實現(xiàn)是否阻止本次導航
Router的實例方法
概念將VueRouter實例對象配置到Vue中后, vue實例就會擁有一個this.$router屬性,this.$router就是當前VueRouter的實例對象。他提供了所有編程式導航的API。
注意router是路由實例對象里面包含著路由的屬性方法,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", query:{wd:1,offset:0}}) }, }, }; </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寫單頁面應用時,會出現(xiàn)打包后的JavaScript包非常大,影響頁面加載,我們可以利用路由的懶加載去優(yōu)化這個問題,當我們用到某個路由后,才去加載對應的組件,這樣就會更加高效
沒有使用懶加載
先引入了組件,事先加載好了。然后不管有沒有使用都已經(jīng)存在
import Vue from 'vue' import VueRouter from 'vue-router' import Home from '../views/Home.vue' Vue.use(VueRouter) const routes = [ { path: '/', name: 'Home', 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 跳轉(zhuǎn)而無須重新加載頁面。
history模式
history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定瀏覽器支持)這兩個方法應用于瀏覽器的歷史記錄棧,在當前已有的 back、forward、go 的基礎之上(方法可在Router的實例方法中查看),它們提供了對歷史記錄進行修改的功能。只是當它們執(zhí)行修改時,雖然改變了當前的 URL,但瀏覽器不會立即向后端發(fā)送請求。
手動設置
效果
hash模式
hash —— 即地址欄 URL 中的 # 符號(此 hash 不是密碼學里的散列運算)。比如這個 URL:http://localhost:8081/#/form hash 的值為 #/form。它的特點在于:hash 雖然出現(xiàn)在 URL 中,但不會被包括在 HTTP 請求中,對后端完全沒有影響,因此改變 hash 不會重新加載頁面。
路由守衛(wèi)
全局路由守衛(wèi)
- router.beforeEach 前置守衛(wèi)
- *router.beforeResolve 前置守衛(wèi)
- *router.afterEach 后置守衛(wèi)
情況一
在使用vue-router開發(fā)的項目中,一般情況下不同路由之間的切換會將離開的路由組件卸載,進入的路由組件掛載。
這種情況下我們可通過vue的聲明周期進行一些頁面的邏輯操作。但是如果有些情況下應用為提高用戶體驗減少卸載頻率或者保存離開組件的活躍性,使用keep-alive組件包裹router-view后路由的切換就把會卸載離開的組件了。這時,如果你的組件需要在路由進入或離開時進行一些操作修改組件自身的數(shù)據(jù)DOM編程等,就不能再依靠vue的生命周期了。這種情況下請使用組件內(nèi)的路由守衛(wèi)。
- beforeRouteEnter 路由組件將要進入
- beforeRouteUpdate (2.2 新增) 路由組件將要更新 -> /music/10086 /music/10010
- beforeRouteLeave 路由組件將要離開
export default { props: ['id'], data() { return { musicUrl: '' } }, beforeRouteEnter (to, from, next) { // 在渲染該組件的對應路由被 confirm 前調(diào)用 // 不!能!獲取組件實例 `this` // 因為當守衛(wèi)執(zhí)行前,組件實例還沒被創(chuàng)建 console.log(undefined) }, beforeRouteUpdate (to, from, next) { // 在當前路由改變,但是該組件被復用時調(diào)用 // 舉例來說,對于一個帶有動態(tài)參數(shù)的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉(zhuǎn)的時候, // 由于會渲染同樣的 Foo 組件,因此組件實例會被復用。而這個鉤子就會在這個情況下被調(diào)用。 // 可以訪問組件實例 `this` }, beforeRouteLeave (to, from, next) { // 導航離開該組件的對應路由時調(diào)用 // 可以訪問組件實例 `this` } }
注意組件獨享的路由守衛(wèi)方法都包含三個參數(shù) to from next
- to : location 本次路由導航跳轉(zhuǎn)的目標路由信息對象
- from : location 本次路由導航從哪個路由信息對象跳轉(zhuǎn)而來()
- next : function 該方法是否允許本次路由跳轉(zhuǎn)
next() // 允許路由跳轉(zhuǎn) next(true) // 允許路由跳轉(zhuǎn) next(false) // 不允許路由跳轉(zhuǎn) next('/') / next({ path: '/' }) // 跳轉(zhuǎn)到一個不同的地址。當前的導航被中斷,然后進行一個新的導航。你可以向 next 傳遞任意位置對象,且允許設置諸如 replace: true、name: 'home' 之類的選項。 // 注意 只有beforeRouteEnter 的next方法可以接受一個回調(diào)函數(shù), // 該回調(diào)函數(shù)接收當前路由組件實例對象作為參數(shù),我們可以通過該參數(shù)操作當前組件 beforeRouteEnter(to, from, next) { console.log(to , from) console.log('組件將要進入,這是組件實例還不存在',this) next(vm => { fetch(`/song/url?id=${vm.id}`) .then((res) => res.json()) .then(({ data }) => { //真實開發(fā)中這里要判斷數(shù)據(jù)是否請求成功 console.log(data[0]); // 把歌曲的數(shù)據(jù)賦值給data vm.musicUrl = data[0]?.url }); }) // 允許路由跳轉(zhuǎn) }
情況二
在使用vue-router開發(fā)的項目中,一般情況下不同路由之間的切換會將離開的路由組件卸載,進入的路由組件掛載。
這種情況下我們可通過vue的聲明周期進行一些頁面的邏輯操作。但是如果有些情況下應用為提高用戶體驗減少卸載頻率或者保存離開組件的活躍性,使用keep-alive組件包裹router-view后路由的切換就吧會卸載離開的組件了這時,如果你的組件需要在路由進入或離開時進行一些操作不需要修改組件自身的狀態(tài)只是判斷是否允許本次路由的跳轉(zhuǎn)等。這種情況下請使用路由獨享守衛(wèi)。
beforeEnter(to, from, next) 當路由將要導航至當前路由時觸發(fā) const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => { // ... } } ] })
案例 登錄驗證 路由獨享守衛(wèi)配置
const routes = [ { path: '/', component: Home }, { path: '/discover', component: () => import('../views/Discover') }, { path: '/mine', component: () => import('../views/Mine'), //路由獨享守衛(wèi) beforeEnter(to, from, next) { // 因為這個守衛(wèi)沒有任何DOM操作或者對組件自身狀態(tài)進行讀寫 // 這樣的守衛(wèi)就可以作為路由獨享守衛(wèi) // 正確的做法存在cookie storage中 if (localStorage.getItem("user")) { next(); } else { // 這里嗎沒有this, next接收一個回調(diào)函數(shù),在回調(diào)函數(shù)中跳轉(zhuǎn) // 下面的寫法進入了個人頁面,又從個人頁面重定向到登錄,這樣可能會造成一些不必要的bug // next((vm) => { // vm.$router.replace('/landr') // }); next({name:'login',params:{to}}); //阻止本次跳轉(zhuǎn),直接導航到指定路由 } } }, { 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') } ] } ]
情況三
全局路由守衛(wèi),當應用中有多個路由都需要進行相同邏輯的路由守衛(wèi)判斷時,并且該邏輯操作中不需要直接操作組件DOM或組件組件的狀態(tài)這是就可以使用全局路由守衛(wèi)(全局守衛(wèi)最常見的應用就是登陸驗證)
beforeEach(to,from,next) 全局前置守衛(wèi)
import Vue from 'vue' import Router from 'vue-router' import Home from '../views/Home' Vue.use(Router) const routes = [ { path: '/', name: 'Home', component: Home }, { path: '/discover', name: 'Discover', component: () => import('../views/Discover') }, { path: '/mine', name: 'Mine', component: () => import('../views/Mine'), }, { 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') } ] } ] const router = new Router({ routes, linkExactActiveClass: 'active' }) // 路由的全局守衛(wèi)所有的路由跳轉(zhuǎn),都會調(diào)用該守衛(wèi) // 全局路由守衛(wèi)也是Vue router應用中,最適合做登錄驗證的地方 router.beforeEach((to, from, next) => { if(to.name === "Mine" || to.name === "Discover") { // 因為這個守衛(wèi)沒有任何DOM操作或者對組件自身狀態(tài)進行讀寫 // 這樣的守衛(wèi)就可以作為路由獨享守衛(wèi) // 正確的做法存在cookie storage中 if (localStorage.getItem("user")) { next(); } else { // 這里嗎沒有this, next接收一個回調(diào)函數(shù),在回調(diào)函數(shù)中跳轉(zhuǎn) // 下面的寫法進入了個人頁面,又從個人頁面重定向到登錄,這樣可能會造成一些不必要的bug // next((vm) => { // vm.$router.replace('/landr') // }); next({ name: 'login', params: { to } }); //阻止本次跳轉(zhuǎn),直接導航到指定路由 } }else { next() } }) export default router
router.beforeResolve(to,from,next) 全局前置守衛(wèi),在beforeEach觸發(fā)之后
router.afterEach(to, from) 全局后置守衛(wèi),該守衛(wèi)路由已經(jīng)離開時觸發(fā),該守衛(wèi)沒有next, next 函數(shù)也不會改變導航本身
到此這篇關于Vue-Router的routes配置詳解的文章就介紹到這了,更多相關Vue-Router routes配置內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- vue3配置router路由并實現(xiàn)頁面跳轉(zhuǎn)功能
- Vue3路由配置createRouter、createWebHistory、useRouter和useRoute詳解
- Vue3實戰(zhàn)學習配置使用vue?router路由步驟示例
- vue-router如何實現(xiàn)history模式配置
- Vue Router history模式的配置方法及其原理
- vue-router的使用方法及含參數(shù)的配置方法
- 使用vue-router為每個路由配置各自的title
- vue router 配置路由的方法
- vue-router+nginx 非根路徑配置方法
- vue中的Router基本配置命令實例詳解
相關文章
使用Vue-router二級路由跳轉(zhuǎn)另一條路由下的子級
這篇文章主要介紹了使用Vue-router二級路由跳轉(zhuǎn)另一條路由下的子級問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10詳解Vue3中shallowRef和shallowReactive的使用
這篇文章主要為大家介紹了Vue3中shallowRef和shallowReactive函數(shù)的使用方法,文中的示例代碼講解詳細,對我們學習Vue有一定的幫助,需要的可以參考一下2022-07-07