Vue的路由及路由鉤子函數(shù)的實(shí)現(xiàn)
什么是路由
什么是路由?網(wǎng)絡(luò)原理中,路由指的是根據(jù)上一接口的數(shù)據(jù)包中的IP地址,查詢路由表轉(zhuǎn)發(fā)到另一個(gè)接口,它決定的是一個(gè)端到端的網(wǎng)絡(luò)路徑。
web中,路由的概念也是類似,根據(jù)URL來將請(qǐng)求分配到指定的一個(gè)'端'。(即根據(jù)網(wǎng)址找到能處理這個(gè)URL的程序或模塊)
使用vue.js構(gòu)建項(xiàng)目,vue.js本身就可以通過組合組件來組成應(yīng)用程序;當(dāng)引入vue-router后,我們需要處理的是將組件(components)映射到路由(routes),然后在需要的地方進(jìn)行使用渲染。
其所包含的功能有:
- 嵌套的路由/視圖表
- 模塊化的、基于組件的路由配置
- 路由參數(shù)、查詢、通配符
- 基于 Vue.js 過渡系統(tǒng)的視圖過渡效果
- 細(xì)粒度的導(dǎo)航控制
- 帶有自動(dòng)激活的 CSS class 的鏈接
- HTML5 歷史模式或 hash 模式,在 IE9 中自動(dòng)降級(jí)
- 自定義的滾動(dòng)條行為
1、基礎(chǔ)路由
當(dāng)我們通過 vue create 創(chuàng)建項(xiàng)目的的時(shí)候,會(huì)選擇是否安裝vue-router,項(xiàng)目創(chuàng)建后,在主組件App.vue中的HTML部分:
<script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script> <div id="app"> <h1>Hello App!</h1> <p> <!-- 使用 router-link 組件來導(dǎo)航. --> <!-- 通過傳入 `to` 屬性指定鏈接. --> <!-- <router-link> 默認(rèn)會(huì)被渲染成一個(gè) `<a>` 標(biāo)簽 --> <router-link to="/foo">Go to Foo</router-link> <router-link to="/bar">Go to Bar</router-link> </p> <!-- 路由出口 --> <!-- 路由匹配到的組件將渲染在這里 --> <router-view></router-view> </div>
上述代碼中,<router-view/>是路由出口,路由匹配到的組件將渲染在這里。
2、在router/index.js文件中
// 0. 如果使用模塊化機(jī)制編程,導(dǎo)入Vue和VueRouter,要調(diào)用 Vue.use(VueRouter) // 1. 定義 (路由) 組件。 可以從其他文件 import 進(jìn)來 const Foo = { template: '<div>foo</div>' } // 2. 定義路由每個(gè)路由應(yīng)該映射一個(gè)組件。 其中"component" 可以是通過 Vue.extend() 創(chuàng)建的組件構(gòu)造器,或者,只是一個(gè)組件配置對(duì)象。 const routes = [ { path: '/foo', component: Foo }, ] // 3. 創(chuàng)建 router 實(shí)例,然后傳 `routes` 配置 const router = new VueRouter({ routes }) // 4. 創(chuàng)建和掛載根實(shí)例。通過 router 配置參數(shù)注入路由,從而讓整個(gè)應(yīng)用都有路由功能 const app = new Vue({ router }).$mount('#app')
3、動(dòng)態(tài)路由
什么是動(dòng)態(tài)路由?動(dòng)態(tài)路由是指路由器能夠自動(dòng)的建立自己的路由表,并且能夠根據(jù)實(shí)際情況的變化實(shí)時(shí)地進(jìn)行調(diào)整。
1、在vue項(xiàng)目中,使用vue-router如果進(jìn)行不傳遞參數(shù)的路由模式,則稱為靜態(tài)路由;如果能夠傳遞參數(shù),對(duì)應(yīng)的路由數(shù)量是不確定的,此時(shí)的路由稱為動(dòng)態(tài)路由。動(dòng)態(tài)路由,是以冒號(hào)為開頭的(:),例子如下:
export default new Router({ routes: [ { path: '/', name: 'HelloWorld', component: HelloWorld }, { path: '/RouterComponents/:id', name: 'RouterComponents', component: RouterComponents } ] })
一個(gè)“路徑參數(shù)”使用冒號(hào) : 標(biāo)記。當(dāng)匹配到一個(gè)路由時(shí),參數(shù)值會(huì)被設(shè)置到 this.$route.params,可以在每個(gè)組件內(nèi)使用。
2、路由跳轉(zhuǎn),執(zhí)行方式有兩大類;
第一大類:router-link模式,直接把參數(shù)寫在to屬性里面:
<router-link :to="{name:'RouterComponents',params:{id:110}}">跳轉(zhuǎn)</router-link>
第二大類:$router.push()模式,代碼如下:
methods: { changeFuc (val) { this.$router.push({ name: 'RouterComponents', params: {id: val} }) } }
或者:
methods: { changeFuc (val) { this.$router.push({ path: `/RouterComponents/${val}`, }) } }
4、路由嵌套
vue項(xiàng)目中,界面通常由多個(gè)嵌套的組件構(gòu)成;同理,URL中的動(dòng)態(tài)路由也可以按照某種結(jié)構(gòu)對(duì)應(yīng)嵌套的各層組件:
const router = new VueRouter({ routes: [ { path: '/user/:id', component: User, children: [ { // 當(dāng) /user/:id/profile 匹配成功, // UserProfile 會(huì)被渲染在 User 的 <router-view> 中 path: 'profile', component: UserProfile }, { // 當(dāng) /user/:id/posts 匹配成功 // UserPosts 會(huì)被渲染在 User 的 <router-view> 中 path: 'posts', component: UserPosts } ] } ] })
5、捕獲所有路由或404 NotFound路由
常規(guī)參數(shù)只會(huì)匹配被 / 分隔的 URL 片段中的字符。如果想匹配任意路徑,我們可以使用通配符 (*):
{ // 會(huì)匹配所有路徑 path: '*' } { // 會(huì)匹配以 `/user-` 開頭的任意路徑 path: '/user-*' }
當(dāng)使用通配符路由時(shí),請(qǐng)確保路由的順序是正確的,也就是說含有通配符的路由應(yīng)該放在最后。路由 { path: '*' } 通常用于客戶端 404 錯(cuò)誤。如果你使用了History 模式,請(qǐng)確保正確配置你的服務(wù)器。
6、編程式導(dǎo)航
聲明式 | 編程式 |
---|---|
<router-link :to="..."> | router.push(...) |
想要導(dǎo)航到不同的 URL,則使用 router.push 方法。這個(gè)方法會(huì)向 history 棧添加一個(gè)新的記錄,所以,當(dāng)用戶點(diǎn)擊瀏覽器后退按鈕時(shí),則回到之前的 URL。
當(dāng)你點(diǎn)擊 <router-link> 時(shí),這個(gè)方法會(huì)在內(nèi)部調(diào)用,所以說,點(diǎn)擊 <router-link :to="..."> 等同于調(diào)用 router.push(...)。
// 字符串 router.push('home') // 對(duì)象 router.push({ path: 'home' }) // 命名的路由 router.push({ name: 'user', params: { userId: '123' }}) // 帶查詢參數(shù),變成 /register?plan=private router.push({ path: 'register', query: { plan: 'private' }})
如果提供了 path,params 會(huì)被忽略
const userId = '123' router.push({ name: 'user', params: { userId }}) // -> /user/123 router.push({ path: `/user/${userId}` }) // -> /user/123 // 這里的 params 不生效 router.push({ path: '/user', params: { userId }}) // -> /user
7、命名路由
由于我們需要通過不同的路由跳轉(zhuǎn)到不同的頁(yè)面,這時(shí)給我們的路由都加一個(gè)名字操作起來會(huì)比較方便
const router = new VueRouter({ routes: [ { path: '/user/:userId', name: 'user', component: User } ] })
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
8、命名視圖
有時(shí)候我們需要一個(gè)布局,這時(shí)候,我們就需要用到命名視圖。
<router-view class="view one"></router-view> <router-view class="view two" name="a"></router-view> <router-view class="view three" name="b"></router-view>
const router = new VueRouter({ routes: [ { path: '/', components: { default: Foo, a: Bar, b: Baz } } ] })
9、嵌套命名視圖
{ path: '/settings', // 你也可以在頂級(jí)路由就配置命名視圖 component: UserSettings, children: [{ path: 'emails', component: UserEmailsSubscriptions }, { path: 'profile', components: { default: UserProfile, helper: UserProfilePreview } }] }
10、路由組件傳參
在組件中使用 $route 會(huì)使之與其對(duì)應(yīng)路由形成高度耦合,從而使組件只能在某些特定的 URL 上使用,限制了其靈活性。
使用 props 將組件和路由解耦:
取代與 $route 的耦合
const User = { template: '<div>User {{ $route.params.id }}</div>' } const router = new VueRouter({ routes: [ { path: '/user/:id', component: User } ] })
通過 props 解耦
const User = { props: ['id'], template: '<div>User {{ id }}</div>' } const router = new VueRouter({ routes: [ { path: '/user/:id', component: User, props: true }, // 對(duì)于包含命名視圖的路由,你必須分別為每個(gè)命名視圖添加 `props` 選項(xiàng): { path: '/user/:id', components: { default: User, sidebar: Sidebar }, props: { default: true, sidebar: false } } ] })
路由鉤子
1、路由鉤子
在某些情況下,當(dāng)路由跳轉(zhuǎn)前或跳轉(zhuǎn)后、進(jìn)入、離開某一個(gè)路由前、后,需要做某些操作,就可以使用路由鉤子來監(jiān)聽路由的變化
全局路由鉤子:router.beforeEach 注冊(cè)一個(gè)全局前置守衛(wèi)
router.beforeEach((to, from, next) => { //會(huì)在任意路由跳轉(zhuǎn)前執(zhí)行,next一定要記著執(zhí)行,不然路由不能跳轉(zhuǎn)了 console.log('beforeEach') console.log(to,from) // next() }) // router.afterEach((to, from) => { //會(huì)在任意路由跳轉(zhuǎn)后執(zhí)行 console.log('afterEach') })
單個(gè)路由鉤子:
只有beforeEnter,在進(jìn)入前執(zhí)行,to參數(shù)就是當(dāng)前路由
routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => { // ... } } ]
路由組件鉤子:
beforeRouteEnter (to, from, next) { // 在渲染該組件的對(duì)應(yīng)路由被 confirm 前調(diào)用 // 不!能!獲取組件實(shí)例 `this` // 因?yàn)楫?dāng)守衛(wèi)執(zhí)行前,組件實(shí)例還沒被創(chuàng)建 }, beforeRouteUpdate (to, from, next) { // 在當(dāng)前路由改變,但是該組件被復(fù)用時(shí)調(diào)用 // 舉例來說,對(duì)于一個(gè)帶有動(dòng)態(tài)參數(shù)的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉(zhuǎn)的時(shí)候, // 由于會(huì)渲染同樣的 Foo 組件,因此組件實(shí)例會(huì)被復(fù)用。而這個(gè)鉤子就會(huì)在這個(gè)情況下被調(diào)用。 // 可以訪問組件實(shí)例 `this` }, beforeRouteLeave (to, from, next) { // 導(dǎo)航離開該組件的對(duì)應(yīng)路由時(shí)調(diào)用 // 可以訪問組件實(shí)例 `this` }
附:完整的導(dǎo)航解析流程
- 導(dǎo)航被觸發(fā)。
- 在失活的組件里調(diào)用離開守衛(wèi)。
- 調(diào)用全局的 beforeEach 守衛(wèi)。
- 在重用的組件里調(diào)用 beforeRouteUpdate 守衛(wèi) (2.2+)。
- 在路由配置里調(diào)用 beforeEnter。
- 解析異步路由組件。
- 在被激活的組件里調(diào)用 beforeRouteEnter。
- 調(diào)用全局的 beforeResolve 守衛(wèi) (2.5+)。
- 導(dǎo)航被確認(rèn)。
- 調(diào)用全局的 afterEach 鉤子。
- 觸發(fā) DOM 更新。
- 用創(chuàng)建好的實(shí)例調(diào)用 beforeRouteEnter 守衛(wèi)中傳給 next 的回調(diào)函數(shù)。
2、路由元信息
定義路由的時(shí)候可以配置 meta 字段:
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, children: [ { path: 'bar', component: Bar, // a meta field meta: { requiresAuth: true } } ] } ] })
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 詳解Vue路由鉤子及應(yīng)用場(chǎng)景(小結(jié))
- 在vue中利用全局路由鉤子給url統(tǒng)一添加公共參數(shù)的例子
- 詳解VueRouter進(jìn)階之導(dǎo)航鉤子和路由元信息
- Vue使用路由鉤子攔截器beforeEach和afterEach監(jiān)聽路由
- 基于Vue2.X的路由和鉤子函數(shù)詳解
- vue-router鉤子函數(shù)實(shí)現(xiàn)路由守衛(wèi)
- Vue2.x與Vue3.x中路由鉤子的區(qū)別詳解
- vue-router之路由鉤子函數(shù)應(yīng)用小結(jié)
- Vue Router組件內(nèi)路由鉤子的使用
相關(guān)文章
Vue獲取HTMLCollection列表的children時(shí)結(jié)果為undefined問題
這篇文章主要介紹了Vue獲取HTMLCollection列表的children時(shí)結(jié)果為undefined問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03Vue?socket.io模塊實(shí)現(xiàn)聊天室流程詳解
vue-socket.io其實(shí)是在socket.io-client(在瀏覽器和服務(wù)器之間實(shí)現(xiàn)實(shí)時(shí)、雙向和基于事件的通信)基礎(chǔ)上做了一層封裝,將socket掛載到vue實(shí)例上,同時(shí)可使用sockets對(duì)象輕松實(shí)現(xiàn)組件化的事件監(jiān)聽,在vue項(xiàng)目中使用起來更方便2022-12-12vue + element ui實(shí)現(xiàn)播放器功能的實(shí)例代碼
這篇文章主要介紹了vue + element ui實(shí)現(xiàn)播放器功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04Vue+Spring Boot簡(jiǎn)單用戶登錄(附Demo)
這篇文章主要介紹了Vue+Spring Boot簡(jiǎn)單用戶登錄,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11如何利用vue+element?ui實(shí)現(xiàn)好看的登錄界面
最近做了個(gè)最基礎(chǔ)的ElementUI登錄頁(yè),適合新手查看,所以下面這篇文章主要給大家介紹了關(guān)于如何利用vue+element?ui實(shí)現(xiàn)好看的登錄界面的相關(guān)資料,需要的朋友可以參考下2022-05-05vue中同時(shí)監(jiān)聽多個(gè)參數(shù)的實(shí)現(xiàn)
這篇文章主要介紹了vue中同時(shí)監(jiān)聽多個(gè)參數(shù)的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04vue緩存的keepalive頁(yè)面刷新數(shù)據(jù)的方法
這篇文章主要介紹了vue緩存的keepalive頁(yè)面刷新數(shù)據(jù)的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-04-04Vue實(shí)現(xiàn)Tab選項(xiàng)卡切換
這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)Tab選項(xiàng)卡切換,點(diǎn)擊不同標(biāo)題顯示對(duì)應(yīng)圖片,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09