[TOC] #### 1. vue-router 介紹 --- Vue-Router 3.x 適用于 Vue2,Vue-Router 4.x 適用于 Vue3 Vue-Router 3.x 官方文檔: <https://router.vuejs.org/zh> vue-router 是 vue 官方的路由插件,它和 vue 是深度集成的,適合用于構(gòu)建單頁面應(yīng)用 #### 2. vue-router 的使用 --- 安裝 vue-router ``` npm install vue-router --save ``` 在模塊化工程中使用 (因為它是一個插件,所以可以通過 Vue.use() 來安裝路由功能) 第一步: 導(dǎo)入路由對象,并且調(diào)用 Vue.use(VueRouter) 第二步: 創(chuàng)建路由實例,并且傳入路由映射配置,導(dǎo)出路由實例 ![](https://img.itqaq.com/art/content/b104b4bfbaa146ffeef4af46e1cbc360.png) 第三步: 在 vue 實例中掛載創(chuàng)建的路由實例 ![](https://img.itqaq.com/art/content/63ef1d32ea92a1044fe3cae85f0788e8.png) #### 3. 路由映射配置的寫法 --- 方案一: 導(dǎo)入組件實例 ```javascript import Home from '@/components/Home'; import About from '@/components/About'; const routes = [ { path: '/home', component: Home }, { path: '/about', component: About }, ] ``` #### 4. 路由的默認(rèn)值、history 模式 --- 剛進(jìn)入頁面路由是 `/`, 可通過路由重定向?qū)崿F(xiàn)默認(rèn)路由 ``` { path: "", redirect: '/home' }, ``` 路由模式默認(rèn)是 hash 模式,在創(chuàng)建路由實例時只需添加 `mode: 'history'` 即可改為 history 模式 ```javascript const router = new VueRouter({ routes, mode: 'history' }) ``` #### 5. router-link 和 router-view 組件 ---- router-link 組件用于生成路由跳轉(zhuǎn)鏈接,to 屬性用于指定路由 ``` <router-link to="/home">首頁</router-link> <router-link to="/about">關(guān)于</router-link> ``` router-link 組件屬性: tag router-link 組件默認(rèn)會被渲染成一個 a 標(biāo)簽,但有些時候我們想要渲染為 li、button 標(biāo)簽等,此時可以使用 tag 屬性 ``` <router-link to="/home" tag="li">首頁</router-link> <router-link to="/about" tag="button">關(guān)于</router-link> ``` router-link 組件屬性: replace 設(shè)置 replace 屬性的話,當(dāng)點(diǎn)擊時,會調(diào)用 router.replace() 而不是 router.push(),于是導(dǎo)航后不會留下 history 記錄 ``` <router-link to="/home" replace>首頁</router-link> ``` router-link 組件屬性: active-class 用于設(shè)置路由激活時的 CSS 類名。默認(rèn)值: "router-link-active",默認(rèn)值可以通過路由的構(gòu)造選項 linkActiveClass 來全局配置 默認(rèn)值 ```html <router-link to="/home">首頁</router-link> <a href="/home" class="router-link-exact-active router-link-active" aria-current="page">首頁</a> ``` 通過 active-class 屬性指定類名 ```html <router-link to="/home" active-class="active">首頁</router-link> <a href="/home" class="router-link-exact-active active" aria-current="page">首頁</a> ``` 通過創(chuàng)建路由實例時的 linkActiveClass 屬性指定類名 ```javascript const router = new VueRouter({ routes, linkActiveClass: "actived" }) ``` #### 6. 通過代碼跳轉(zhuǎn)路由 this.$router.push() --- replace 不會留下 history 記錄 ```javascript this.$router.push('/home') this.$router.replace('/home') ``` #### 7. 動態(tài)路由的使用 --- 路由映射配置: 定義一個動態(tài)參數(shù) userId ```javascript { path: '/user/:userId', component: User } ``` 進(jìn)行路由跳轉(zhuǎn)時 userId 是動態(tài)獲取的 ```html <router-link :to="'/user/' + userId">檔案</router-link> ``` 在 User 組件中獲取動態(tài)參數(shù) userId ($route: 當(dāng)前處于活躍狀態(tài)的路由) ``` <p>{{ $route.params.userId }}</p> ``` #### 8. 路由組件的懶加載 --- 執(zhí)行打包命令 ``` npm run build ``` 當(dāng)前應(yīng)用程序開發(fā)的所有業(yè)務(wù)代碼都在一個文件中(前綴為 app 的 js 文件) 第三方插件的東西都會打包到 vendor 前綴的 js 文件中 manifest 前綴的 js 文件是為我們打包的代碼做底層支撐的 (commonjs、ES6 語法) ![](https://img.itqaq.com/art/content/b4f2067ad211a71f620fa418a5affc96.png) 因為業(yè)務(wù)代碼都在一個文件中,當(dāng)打包構(gòu)建應(yīng)用時,JavaScript 包會變得非常大,影響頁面加載,那么用戶就會出現(xiàn)短暫空白的情況,所以我們應(yīng)該想個辦法將存放業(yè)務(wù)代碼的 `app.*.js` 文件進(jìn)行分離 如果我們能把不同路由對應(yīng)的組件分割成不同的代碼塊,然后當(dāng)路由被訪問的時候才加載對應(yīng)組件,這樣就更加高效了 路由懶加載的主要作用就是將路由對應(yīng)的組件打包成一個個的 js 代碼塊,只有在這個路由被訪問到時,才加載對應(yīng)的組件 路由懶加載的寫法 ```javascript { path: '/home', component: () => import('@/components/Home') } ``` 如下圖所示,三個路由映射使用了懶加載生成了三個對應(yīng)的 js 文件 ![](https://img.itqaq.com/art/content/644c4c7a40769471fd26e341d7997afb.png) #### 9. 嵌套路由的使用 --- Home 組件 ```html <template> <div> <h2>我是首頁</h2> <p>首頁內(nèi)容,哈哈哈</p> <router-link to="/home/news">新聞</router-link> <router-link to="/home/message">消息</router-link> <router-view></router-view> </div> </template> ``` 路由映射配置 (嵌套路由: /home/news、/home/message): ``` { path: '/home', component: Home, children: [ { path: '', redirect: 'news' }, { path: 'news', component: HomeNews }, { path: 'message', component: HomeMessage }, ] }, ``` #### 10. vue-router 參數(shù)傳遞 --- 傳遞參數(shù)主要有兩種方式: params 和 query | 類型 | 配置路由 | 傳遞方式 | 使用示例 | | ------------ | ------------ |------------ |------------ | | params | /router/:id | 在 path 后面跟上對應(yīng)的值 | /router/10 | | query | /router | 對象中使用 query 的 key 作為傳遞方式 | /router?id=10 | router-link 組件 query 方式傳遞參數(shù) ```html <router-link :to="{path: '/profile', query: {id: 10, name: 'liang'}}">檔案</router-link> ``` js 代碼以 query 方式傳遞參數(shù) ```javascript this.$router.push({ path: "/profile", query: { id: 10, name: "liang", }, }); ``` 在 Profile 組件中獲取 query 方式傳遞的參數(shù) ```html <template> <div> <h2>我是Profile組件</h2> <p>{{ $route.query.id }}</p> <p>{{ $route.query.name }}</p> <button @click="btnClick">點(diǎn)擊</button> </div> </template> ``` #### 11. 導(dǎo)航守衛(wèi)的認(rèn)識和基本使用 --- 導(dǎo)航守衛(wèi)就是路由跳轉(zhuǎn)過程中的一些鉤子函數(shù) (導(dǎo)航: 表示路由正在發(fā)生改變, 守衛(wèi): 可以理解為鉤子) 需求: 給每個路由組件設(shè)置單獨(dú)的網(wǎng)頁標(biāo)題 title 路由映射配置中添加 meta.title 屬性,用于設(shè)置網(wǎng)頁標(biāo)題 (meta 是路由元信息, 也稱為元數(shù)據(jù), 就是用于描述數(shù)據(jù)的數(shù)據(jù)) ``` { path: '/home', component: Home, meta: { title: '首頁' } }, { path: '/about', meta: { title: '關(guān)于' }, component: About }, ``` 全局前置守衛(wèi) ```javascript router.beforeEach((to, from, next) => { document.title = to.matched[0].meta.title next() }) ``` 補(bǔ)充: 全局后置守衛(wèi) ```javascript router.afterEach((to, from)=>{ console.log('afterEach ....') }) ``` 路由獨(dú)享守衛(wèi)需要在路由映射配置中定義: ```javascript { path: '/about', component: About, beforeEnter: (to, from, next) => { console.log('about 路由獨(dú)享守衛(wèi)執(zhí)行') next() } }, ``` #### 12. keep-alive 組件的使用 --- keep-alive 是 vue 內(nèi)置的一個組件,可以使被包含的組件保留狀態(tài),或避免重新渲染 router-view 是 vue-router 中的組件,如果被包在 keep-alive 里面,所有路徑匹配到的視圖組件都會被緩存 嵌套路由保持組件選中狀態(tài): ``` data() { return { path: "/home/news", }; }, activated() { // 當(dāng)組件處于活躍狀態(tài)時觸發(fā) this.$router.push(this.path); }, beforeRouteLeave(to, from, next) { // 導(dǎo)航離開該組件的對應(yīng)路由時調(diào)用 // 可以訪問組件實例 `this` this.path = this.$route.path; next(); }, ``` 有些時候我們可能只需要部分組件被緩存,此時可以通過 include 或 exclude 屬性來處理 include 只有匹配的組件會被緩存,exclude 匹配的組件不會被緩存 exclude 屬性值是組件導(dǎo)入的 name 屬性值,多個使用逗號分隔 ```html <keep-alive exclude="User,Profile"> <router-view /> </keep-alive> ```