<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] >[success] # 路由詳解(二)----進階篇 <br> >[success] ## 路由組件傳參(.vue文件路由跳頁傳參) 我們如果在一個頁面中 **需要根據路由獲取參數, 在頁面中用參數做一些邏輯處理**,首先可以使用 **路由** 的實例 **$route** 來 **獲取路由的參數** , 但是這樣有一個 **缺點** ,我們的 **頁面** 和 **路由** 進行了 **高度耦合** ,為了 **解耦** ,使我們的組件能在最大程度上 **復用** , 我們就會用到 **路由組件傳參** , **路由組件傳參** 有 **3種** 模式: >[success] ### 布爾模式 **布爾模式**: 適用于在 **路由對象** 中有 **路由參數(例如:path: '/about/:name')** 的 **路由配置**。 **場景** : 我有一個 **demo.vue頁面** 中使用 **$route.params.name** 在頁面中進行 **邏輯判斷** ,這樣 **耦合性就很高** ,只能用 **$route.params.name** 方式判斷,其他頁面想使用這個 **demo.vue頁面** 也只能通過 **路由傳參** 的方式使用該頁面,如果使用了 **布爾模式** , **demo.vue頁面** 中就可以在 **props** 中設置 **name** 屬性,頁面中可以直接使用 **name** 屬性,而不是這樣使用 **$route.params.name** ,這樣其他頁面使用 **demo.vue頁面** 作為 **組件** 使用可以直接寫 : ~~~ <demo :name="'小明'" /> ~~~ 這樣的話 **demo.vue** 的 **name參數** 即可以用 **路由params方式傳參** ,也可以用 **父傳子的props方式傳參**。 2. **布爾模式使用方法有2種如下**: >[success] #### 字符串模板拼接方式 1. 首先在 **router.js文件** 對應頁面的 **路由對象** 中設置 **props屬性** 置為 **true** , **$route.params 將會被設置為組件屬性**,所以 **query的傳參方式是不好用的** , **路由對象的path屬性** 一定要是 **屬性拼接** ( **path:'/about/:name/:age'** )或者 **params** 的寫法。 **router.js** ~~~ import Home from '@/views/Home' export default [ { path: '/', name: 'home', component: Home }, { path: '/about/:name/:age', // 1. 路由參數 name: 'about', component: () => import('@/views/About.vue'), props: true // 2. 開啟布爾模式 } ~~~ 2. 在 **Home.vue** 頁面通過 **點擊事件** 跳轉 **About.vue** 頁面,給 **path屬性** 用 **字符串模板** 進行 **參數拼接** 的方式進行 **傳參** 。 **Home.vue** ~~~ <template> <div> <button @click="handleClick">點擊我跳轉About頁面</button> </div> </template> <script> export default { data(){ return{ name: '小明', age: '18' } }, methods: { handleClick(){ this.$router.push({ path: `/about/${ this.name }/${ this.age }`, // 3. 向跳轉的頁面傳參 }) } } } </script> ~~~ 3. 在 **使用參數的頁面(About.vue)中** 用 **props設置屬性** ,可以給 **屬性** 設置 **類型(支持多種類型,數組形式即可)、默認值** ,這種方式可以直接在使 **template標簽** 中使用 **name** 屬性,不用像之前用 **$route** 的形式使用 **參數** ,具體寫法如下: **About.vue** ~~~ <template> <div> 我的名字叫{{ name }},今年{{ age }}歲 </div> </template> <script> export default{ props: { // 4. 設置參數在頁面中使用 name: { // 參數名稱 type: String, // 類型,支持數組形式例如:type: [String, Number] default: '我是默認值的name' // 默認值 }, age: { // 參數名稱 type: String, // 類型,支持數組形式例如:type: [String, Number] default: '10' // 默認值 }, } } </script> ~~~ >[success] #### params方式 1. **params** 跟 **字符串模板拼接方式** 的不同點就是 **Home.vue** 頁面的傳參寫法不一樣。 **Home.vue** ~~~ handleClick(){ this.$router.push({ // params方式傳參 name: 'about', params: { // 向跳轉的頁面傳參 name: this.name, age: this.age } }) ~~~ >[success] ### 對象模式 **對象模式**:如果 **router.js** 中的 **路由對象** 的 **props** 是一個 **對象** , **props對象** 中的 **屬性** 為 **組件屬性** 。**當props是靜態的時候有用**。 **場景**: 也就是說使用 **對象模式** 時,該頁面會**有一個靜態寫死的props屬性(跟props的default屬性有一點像,但它不支持修改)**,而且不支持 **動態修改**,如果想修改,只能 **手動** 去 **router.js** 中對應的 **路由對象** 中 **修改props對象中的屬性**。 >[success] #### 對象模式使用方法 1. 在 **router.js** 中設置 **props屬性** 為 **對象形式**, 它的 **key** 作為 **組件屬性** , 如果 **props對象** 中 **不寫屬性** , 會顯示對應頁面中 **props對象** 中 **default** 屬性的默認值。 **router.js** ~~~ import Home from '@/views/Home' export default [ { path: '/', name: 'home', component: Home }, { path: '/about', name: 'about', component: () => import(/* webpackChunkName: "about" */ '@/views/About.vue'), props: { name: '小黑' // 這里不寫name屬性,就會顯示props中設置的默認值小明 } } ] ~~~ 2. **從 Home.vue 頁面通過點擊事件跳轉 About.vue 中**,強調一下,用 **對象模式傳參是無效的**。 **Home.vue** ~~~ <template> <div> <button @click="handleClick">點擊我跳轉About頁面</button> </div> </template> <script> export default { methods: { handleClick(){ this.$router.push({ // 方案1 name: 'about' }) // this.$router.push({ // 方案2 // path: '/about' // })} } } </script> ~~~ 3. **About.vue** 頁面也正常寫 **props對象屬性默認值、類型** 即可。 **About.vue** ~~~ <template> <div> {{ name }} </div> </template> <script> export default{ props: { name: { // 參數名稱 type: String, // 類型,支持數組形式例如:type: [String, Number] default: '小明' // 默認值 } } } </script> ~~~ >[success] ### 函數模式 **函數模式** : **根據當前的路由傳入的參數,來做一些處理邏輯** ,從而 **設置我們傳入組件的屬性值**。這么說不太容易懂,簡單的說就是 **可以根據傳入的 params 或者 query 對象中的參數,在函數中進行判斷邏輯,最終給頁面傳出路由參數**。 **場景** : 有 **a.vue** 、 **b.vue** 、 **c.vue 3** 個頁面,**a** 和 **b頁面** 都要跳轉到 **c頁面** 并且用 **params** (或者 **query** )傳入 **name** 、 **alias屬性** ,**c頁面** 的 **路由對象** 的 **props函數** 中需要判斷 **name** 是否等于 **孫悟空** ,如果等于 **孫悟空** ,就把 **alias** 屬性值 **弼馬溫** 賦的給 **name**,這樣就做到了 **在路由層面直接處理要展示的值**,代碼如下: <br/> 1. 在 **router.js** 中給 **c.vue** 設置 **props屬性** 為 **函數** ,它有一個 **回調參數route對象**, **route對象** 中可以取到 **當前路由對象信息,包括:params、query等**,并且通過 **route對象** 取到 **route.query.name** 來進行判斷是否等于 **孫悟空**, 如果等于 **孫悟空**,就用它的 **alias(別名)** **弼馬溫** 作為 **name** 展示。 **router.js** ~~~ export default [ { path: '/', name: 'a', component: () => import('@/views/a.vue') }, { path: '/b', name: 'b', component: () => import('@/views/b.vue') }, { path: '/c', name: 'c', component: () => import('@/views/c.vue'), // route代表當前路由對象(里面能取到params、query對象中的參數信息), return一個對象, // 對象中的name屬性對應c頁面中props的name屬性,這里的name: route.query.name完全取決于 // 傳值的頁面使用哪種方式(query、params)傳值 props: route => ({ name: route.query.name === '孫悟空' ? route.query.alias : route.query.name }) } ] ~~~ **a.vue** ~~~ <template> <div> <p>a頁面</p> <button @click="handleClick">跳轉c頁面</button> </div> </template> <script> export default { methods: { handleClick(){ this.$router.push({ // query方式傳參 path: '/c', query: { name: '孫悟空', alias: '弼馬溫' } }) } } } </script> ~~~ **b.vue** ~~~ <template> <div> <p>b頁面</p> <button @click="handleClick">跳轉c頁面</button> </div> </template> <script> export default { methods: { handleClick(){ this.$router.push({ // query方式傳參 path: '/c', query: { name: '豬八戒', alias: '豬剛鬣' } }) } } } </script> ~~~ **c.vue** ~~~ <template> <div> 我的名字叫{{ name }} </div> </template> <script> export default{ props: { name: { // 參數名稱 type: String, // 類型,支持數組形式例如:type: [String, Number] default: '墨跡嘴唐僧' // 默認值 } } } </script> ~~~ >[success] ## HTML5 History模式 參考文章:[Vue番外篇 -- vue-router淺析原理](https://juejin.im/post/5bc6eb875188255c9c755df2#heading-2) **vue-router** 默認 **hash模式** ,在 **URL** 中會有一個 **# 號** ,一般場景下,**hash** 和 **history** 都可以,除非你更在意顏值, **#號** 夾雜在 **URL** 里看起來確實有些不太美麗。 <br> 1. **hash** —— 即地址欄 **URL** 中的 **#號** (此 hash 不是密碼學里的散列運算)。 比如這個 **URL**: **http://www.abc.com/#/hello**, **hash** 的值為 **#/hello** 。它的特點在于: **hash** 雖然出現在 **URL** 中,但不會被包括在 **HTTP請求** 中,對后端完全沒有影響,因此 **改變 hash 不會重新加載頁面**。 2. **history** —— 利用了 **HTML5 History Interface** 中新增的 **pushState()** 和 **replaceState()** 方法。(需要特定瀏覽器支持) 這兩個方法應用于瀏覽器的歷史記錄棧,在當前已有的 **back** 、**forward**、**go** 的基礎之上,它們提供了對 **歷史記錄進行修改*** 的功能。只是當它們執行修改時,雖然改變了當前的 **URL**,但**瀏覽器不會立即向后端發送請求**。 因此可以說,**hash模式** 和 **history模式** 都屬于 **瀏覽器自身的特性**,**vue-router** 只是利用了這 **兩個特性**(通過調用瀏覽器提供的接口)來實現 **前端路由**。 3. **abstract模式** —— **abstract模式** 是使用一個 **不依賴于瀏覽器的瀏覽歷史虛擬管理后端**。 根據平臺差異可以看出,在 **Weex 環境** 中只支持使用 **abstract模式** 。 不過,**vue-router 自身會對環境做校驗,如果發現沒有瀏覽器的 API,vue-router 會自動強制進入 abstract 模式**,所以 在 **使用 vue-router 時只要不寫 mode 配置即可,默認會在瀏覽器環境中使用 hash 模式,在移動端原生環境中使用 abstract 模式**。 (當然,你也可以明確指定在所有情況下都使用 **abstract 模式** ) >[success] ### History模式配置 1. 默認 **router.js** 中的 **mode(模式)** 屬性是 **hash**,在 **RRL** 中會有 **# 符號** ,例如: **[http://localhost:8080/#/](http://localhost:8080/#/)** ~~~ import Vue from 'vue' import Router from 'vue-router' import routes from './router' Vue.use(Router) export default new Router({ mode: 'hash', // 默認哈希模式 routes }) ~~~ 2. 但是在 **正式環境** 時候,我們不希望看到這個 **# 符號**,把 **mode** 修改成 **history模式**,它是使用的 **history**的一些 **api** 來做頁面的 **無刷新跳轉** ~~~ export default new Router({ mode: 'history', // history模式 routes }) ~~~ 3. 使用 **history模式** ,所有 **匹配不到靜態資源的頁面** 的 **URL** 都會指向 **index.html** ,這樣會有一個問題 **當你匹配不到靜態資源,前端路由也匹配不到組件的話**,這時候就會有問題了,所以需要在 **router.js路由列表** 里 **最后(為什么是最后,因為路由列表是有優先原則的,順序的從上到下的讀取順序,如果兩個組件name都叫同樣的名字,它會使用上面的組件)** 添加一項 **404頁面** 的 **路由對象**。 **router.js** ~~~ { // 一定要寫在路由列表的最后面 path: '*', // * 符號,代表匹配任何的路徑 component: () => import('@/views/error_404.vue') } ~~~ 4. 當然 **history模式** 也是需要 **后端配合** 后期視頻講到部署時候這里補寫上 >[success] ## 導航守衛 **導航守衛** :在 **路由發生跳轉** 到 **導航結束** 這段時間能做一些相應的 **邏輯處理** 。 | 導航守衛名稱 | 導航守衛方法 | 參數 | 應用場景 | | --- | --- | --- | --- | | 全局前置守衛 | router.beforeEach | **參數** 是一個 **回調函數** ,router.beforeEach((to, from, next) => { })<br> 1. **to** :代表 **要跳轉的頁面** <br> 2. **from** :代表 **從哪個頁面跳轉來** <br> 3. **next** : **next** 是一個函數,執行 **next()** 代表 **繼續跳轉要去的頁面** | **判斷是否登錄** ,如果 **未登錄跳轉到登錄頁面** , **已登錄的話就跳轉想去的頁面** | | 全局解析守衛 | router.beforeResolve | **參數** 跟 **router.beforeEach** 相同 | 后期補上。暫時不知道應用場景 | | 全局后置鉤子 | router.afterEach | **參數** 里沒有 **next** 其他 **參數** 都跟 **router.beforeEach** 相同 | **跳轉頁面完畢** 之后 **關閉loading** | | 路由獨享守衛 | beforeEnter | **參數** 跟 **router.beforeEach** 相同 | 能對 **單獨的路由頁面進行邏輯處理** | | 組件內的守衛 | 1. beforeRouteEnter | **參數** 跟 **router.beforeEach** 相同 | 1. **進入頁面時觸發** <br>2. 不能 **獲取組件實例this** ,如果想使用 **this** ,用 **next(vm => {})** 方式。 | | | 2. beforeRouteLeave | **參數** 跟 **router.beforeEach** 相同 | 1. **離開頁面時觸發** <br>2. 可以 **獲取組件實例this**| | | 3. beforeRouteUpdate | **參數** 跟 **router.beforeEach** 相同 | 1. **路由發生變化,組件被復用時觸發** <br>2. 可以 **獲取組件實例this** | >[success] ### 全局前置守衛 **場景** :比如在 **跳轉一個頁面時要判斷這個用戶有沒有登錄過,如果沒有登錄過要跳轉到登錄頁面,如果登錄過就跳轉要跳轉的頁面** ,以及做一些 **路由權限** 的 **判斷處理** 。 1. 你可以使用 **router.beforeEach** 注冊一個 **全局前置守衛** ,在里面寫 **判斷跳轉頁面是否登錄的邏輯**,代碼如下: **router / index.js** ~~~ import Vue from 'vue' import Router from 'vue-router' import routes from './router' Vue.use(Router) const router = new Router({ routes }) // 這個登錄狀態是由接口來返回的,這里只是模擬一下登錄跳轉邏輯 const HAS_LOGINED = false // 注冊全局前置守衛 router.beforeEach((to, from, next) => { if(to.name !== 'login'){ // 訪問的頁面不是 【登錄頁面】 // 【已登錄】就繼續跳轉要去的頁面 if(HAS_LOGINED) next() // 【未登錄】跳轉到login頁面。next方法里面傳入的參數跟$router.push同樣 else next({ name: 'login' }) } else { // 訪問的頁面是 【登錄頁面】 // 【已登錄】就跳轉到首頁 if(HAS_LOGINED) next({ name: 'home' }) // 【未登錄】跳轉到登錄頁 else next() } }) export default router ~~~ **router / router.js** ~~~ import Home from '@/views/Home' export default [ { path: '/', name: 'home', alias: '/home_page', component: Home, }, { path: '/login', name: 'login', component: () => import('@/views/login.vue'), }, { path: '*', // * 符號,代表匹配任何的路徑 component: () => import('@/views/error_404.vue') } ] ~~~ **login.vue** ~~~ <template> <div>登錄頁面</div> </template> ~~~ >[success] ### 全局解析守衛 **全局解析守衛** :在 **導航被確認之前** ,**異步路由組件被解析之后**, **解析守衛** 就被調用。 1. 問:什么叫 **導航被確認之前?** 答: **所有導航鉤子(導航守衛)都結束,導航就是被確定了** 。 2. 問: 什么叫 **路由組件被解析之后** ? 答:頁面渲染后。 **用法**: ~~~ import Vue from 'vue' import Router from 'vue-router' import routes from './router' import { Loading } from 'element-ui'; // 注冊路由 Vue.use(Router) // vue-router實例 const router = new Router({ routes }) // 全局解析守衛 router.beforeResolve((to, from, next) => { // 邏輯處理 next() }) export default router ~~~ >[success] ### 全局后置鉤子 **場景** :我們在跳轉頁面時候要在 **全局前置守衛(router.beforeEach)** 中執行 **打開 Loading 加載提示** ,跳轉完畢后需要在 **全局后置鉤子(router.afterEach)** 中 **關閉 Loading 加載提示** 。 **router / index.js** ~~~ import Vue from 'vue' import Router from 'vue-router' import routes from './router' import { Loading } from 'element-ui'; // 注冊路由 Vue.use(Router) // vue-router實例 const router = new Router({ routes }) // 登錄狀態 const HAS_LOGINED = true // loading實例 let loadingInstance = null // 注冊全局前置守衛 router.beforeEach((to, from, next) => { // 打開loading loadingInstance = Loading.service({ lock: true, // 鎖定屏幕滾動 text: '拼命加載中... >_<', // 提示文字 spinner: 'el-icon-loading', // 自定義加載圖標類名 background: 'rgba(0, 0, 0, 0.7)' // loading背景顏色 }) // 是否登錄頁面跳轉邏輯 if(to.name !== 'login'){ if(HAS_LOGINED) next() else next({ name: 'login' }) } else { if(HAS_LOGINED) next({ name: 'home' }) else next() } }) // 注冊全局后置鉤子 router.afterEach((to, from) => { // 關閉loading loadingInstance && loadingInstance.close() }) export default router ~~~ >[success] ### 路由獨享守衛 **路由獨享守衛** : 給 **指定的路由添加路由守衛** ,**單獨做邏輯處理**。 **用法**: 1. 在想要 **進行邏輯處理頁面** 的 **路由對象** 中寫上 **beforeEnter屬性** ,屬性的參數跟 **router.beforeEach** 相同。 ~~~ import Home from '@/views/Home' export default [ { path: '/', name: 'home', alias: '/home_page', component: Home }, { path: '/about', name: 'about', component: () => import('@/views/About.vue'), beforeEnter: (to, from, next) => { // 在里面進行邏輯處理 if(from.nmae === 'home') alert('這是從home頁來的') else alert('這不是從home頁來的') next() } } ] ~~~ >[success] ### 組件內的守衛 每個 **組件** 都可以有 **3個鉤子** 包括: **beforeRouteEnter** 、 **beforeRouteLeave** 、 **beforeRouteUpdate** **組件內的守衛** : 在 **組件進入(beforeRouteEnter)** 、 **組件離開(beforeRouteLeave )** 、 **組件改變(beforeRouteUpdate)** 頁面時觸發。 >[success] #### beforeRouteEnter **beforeRouteEnter** : 渲染 **組件** 的 **對應路由** ,被確認前調用(跳轉 **對應頁面** 時 **beforeRouteEnter** 才會 **被調用** ) **用法** : 1. **Home.vue** ~~~ <template> <div> 我是Home.vue頁面 </div> </template> <script> export default { beforeRouteEnter(to, from, next){ // 參數跟beforeEach方法一樣 next() } } </script> ~~~ 2. **需要注意**: **beforeRouteEnter** 是在 **路由觸發要進頁面的時候調用** ,此時 **頁面還沒有渲染** ,所以此時在 **beforeRouteEnter** 中 **訪問組件實例 this** 是無效的,如下: ~~~ <script> export default { data(){ return{ name: '星哥' } }, beforeRouteEnter(to, from, next){ // 參數跟beforeEach方法一樣 console.log(this.name) // Cannot read property 'name' of undefined 此時是取不到this實例的 next() } } </script> ~~~ 如果想 **訪問組件實例 this** 的話可以這樣寫: ~~~ <script> export default { data(){ return{ name: '星哥' } }, beforeRouteEnter(to, from, next){ // 參數跟beforeEach方法一樣 next(vm => { // vm是組件的實例 console.log(vm,'vm') }) } } </script> ~~~ >[success] #### beforeRouteLeave **beforeRouteLeave** :在頁面要離開時觸發 **beforeRouteLeave** 。 **補充一句 beforeRouteLeave** 可以 **訪問組件實例this** 。 用法: 1. 例如現在有個 **編輯頁面**,還沒 **編輯** 完,就要 **跳轉其他頁面** ,此時要彈出一個 **提示信息:您確定要離開嗎?** ,代碼如下: **Home.vue** ~~~ <template> <div> 我是Home.vue頁面 </div> </template> <script> export default { beforeRouteLeave(to, from, next) { // 參數跟beforeEach方法一樣 const leave = confirm('您確定要離開嗎?') if(leave) next() // 確定離開 else next(false) // 取消離開 }, } </script> ~~~ >[success] #### beforeRouteUpdate **beforeRouteUpdate** : **路由發生變化,組件被復用時觸發 beforeRouteUpdate** 。**補充一句 beforeRouteUpdate** 可以 **訪問組件實例this** 。 **用法**: 1. 在 **router.js** 中配置好 **路由對象** 信息。 **router.js** ~~~ import Home from '@/views/Home' export default [ { path: '/', name: 'a', component: () => import('@/views/a.vue') }, { path: '/c/:name', name: 'c', component: () => import('@/views/c.vue'), props: true // 開啟布爾模式 } ] ~~~ **a.vue** ~~~ <template> <div> <p>我是a頁面</p> <button @click="handleClick">點擊我跳轉c頁面</button> </div> </template> <script> export default { methods: { handleClick() { this.$router.push({ // params方式傳參 name: 'c', params: { name: '小a' } }) } } } </script> ~~~ 重點是下面這個 **c.vue** , 在 **c.vue** 中使用了 **c.vue** ,也就是應了上面那句話: **路由發生變化,組件被復用時觸發 beforeRouteUpdate** ,下面的 **c.vue** 中路由參數 **name發生變化** ,同時 **組件也被復用** 。 **c.vue** ~~~ <template> <div> <p>{{ name }}</p> <p>我是c頁面</p> <button @click="handleClick">點我還跳轉c頁面</button> </div> </template> <script> export default{ props: { name: { // 參數名稱 type: String, // 類型,支持數組形式例如:type: [String, Number] default: '小c' // 默認值 } }, methods: { handleClick() { this.$router.push({ // params方式傳參 name: 'c', params: { name: '小c2', } }) } }, beforeRouteUpdate(to, from, next){ console.log(to.name, from.name) // c c next() } } </script> ~~~ >[success] ### 完整的導航解析流程(vue-router鉤子生命周期執行順序) 1. 導航被觸發(**this.$router.push** 或者 **修改URL** 觸發) 2. 在失活的組件(**即將離開的頁面組件**)里調用 **beforeRouteLeave** 守衛 3. 調用全局的前置守衛 **beforeEach** 4. 在重用的組件里調用 **beforeRouteUpdate** 5. 調用路由獨享的守衛 **beforeEnter** 6. 解析異步路由組件 7. 在被激活的組件里(**即將計入的頁面組件**)里調用 **beforeRouteEnter** 8. 調用全局的解析守衛 9. 導航被確認 10. 調用全局的后置守衛 **afterEach** 11. 觸發 **DOM** 更新 12. 用創建好的實例調用 **beforeRouteEnter** 守衛中傳給 **next** 的**回調函數(next (vm => {}))**。 >[success] ## 路由元信息 **路由元信息**:每個 **路由對象** 都有一個 **meta** 屬性,里面可以 **配置一些權限** 。 **場景**:例如 **title** , 默認的 **title** 是在 **index.html** 文件中寫死的,如果想每個頁面有不同的 **title** , **home** 的 **title** 是 【首頁】, **about** 的 **title** 是 【關于】,就要在對應的 **路由對象** 中配置 **meta** 配置。 **用法** : 1. 在 **路由列表** 中的 **路由對象** 上設置 **title** 信息 **router/router.js** ~~~ import Home from '@/views/Home' export default [ { path: '/', name: 'home', alias: '/home_page', component: Home, meta: { // 配置title信息 title: '首頁' } }, { path: '/about', name: 'about', component: () => import('@/views/About.vue') }, { path: '*', // * 符號,代表匹配任何的路徑 component: () => import('@/views/error_404.vue') } ] ~~~ 2. 在 **全局前置守衛(router.beforeEach)** 中通過 **setTitle方法** 動態設置 **title** **router/index.js** ~~~ import Vue from 'vue' import Router from 'vue-router' import routes from './router' import { Loading } from 'element-ui'; import { setTitle } from '@/lib/util' // 注冊路由 Vue.use(Router) // vue-router實例 const router = new Router({ routes }) // 登錄狀態 const HAS_LOGINED = true // loading實例 let loadingInstance = null // 注冊全局前置守衛 router.beforeEach((to, from, next) => { // 動態設置title to.meta && setTitle(to.meta.title) // 打開loading loadingInstance = Loading.service({ lock: true, // 鎖定屏幕滾動 text: '拼命加載中... >_<', // 提示文字 spinner: 'el-icon-loading', // 自定義加載圖標類名 background: 'rgba(0, 0, 0, 0.7)' // loading背景顏色 }) // 是否登錄頁面跳轉邏輯 if(to.name !== 'login'){ if(HAS_LOGINED) next() else next({ name: 'login' }) } else { if(HAS_LOGINED) next({ name: 'home' }) else next() } }) // 注冊全局后置鉤子 router.afterEach((to, from) => { // 關閉loading loadingInstance && loadingInstance.close() }) export default router ~~~ 3. 引入 **setTitle方法**, 如果 **路由對象** 中沒有設置 **title屬性**的,會自動設置為 **admin** 。 **lib/util.js** ~~~ export const setTitle = (title) => { window.document.title = title || 'admin' // 默認title } ~~~ >[success] ## 過渡動效 **過渡動效**: 頁面的 **切換** 就是 **一個組件注銷,一個組件加載** ,過渡動效就是 **給頁面跳轉時添加過渡效果** 。 用法: 1. 在 **app.vue** 頁面中用 **transition-group** 標簽包裹 **多個視圖組件(router-view )** ,如果只有一個 **視圖組件** , 用 **transition** 標簽包裹,需要給視圖組件設置 **key** ,**transition-group**標簽設置 **name** ,這里的 **name** 對應下面的 **style** 標簽 **class** 類名前綴。 ~~~ <template> <div id="app"> <!-- 多個視圖組件(router-view)用transition-group標簽包裹,如果只有一個視圖組件用transition標簽包裹即可。 --> <transition-group name="router"> <router-view key="default"/> <router-view key="email" name="email"/> <router-view key="tel" name="tel"/> </transition-group> </div> </template> <style lang="scss"> // 頁面進入的效果 .router-enter{ // 初始化加載狀態 opacity: 0; } .router-enter-active{ // 設置組件從無到有的過程 transform: opacity 1s ease; } .router-enter-to{ // 頁面完全顯示之后 opacity: 1; } // 頁面離開的效果 .router-leave{ // 初始化加載狀態 opacity: 1; } .router-leave-active{ // 設置組件從無到有的過程 transform: opacity 1s ease; } .router-leave-to{ // 頁面完全顯示之后 opacity: 0; } </style> ~~~ 2. 或者也可以寫成 **動態類名**, **根據路由參數來決定**,如果你想為 **某個頁面設置特定的動畫效果** ,可以使用這種方式,寫法如下: ~~~ <template> <div id="app"> <!-- 多個視圖組件(router-view)用transition-group標簽包裹,如果只有一個視圖組件用transition標簽包裹即可。 --> <transition-group :name="routerTransition"> <router-view key="default"/> <router-view key="email" name="email"/> <router-view key="tel" name="tel"/> </transition-group> </div> </template> <script> export default{ data(){ return{ routerTransition: '' // 類名 } }, watch:{ '$route'(to){ // 監聽路由參數變化改變過渡效果的類 to.query && to.query.transitionName && (this.routerTransition = to.query.transitionName) } } } </script> <style lang="scss"> // 頁面進入的效果 .router-enter{ // 初始化加載狀態 opacity: 0; } .router-enter-active{ // 設置組件從無到有的過程 transform: opacity 1s ease; } .router-enter-to{ // 頁面完全顯示之后 opacity: 1; } // 頁面離開的效果 .router-leave{ // 初始化加載狀態 opacity: 1; } .router-leave-active{ // 設置組件從無到有的過程 transform: opacity 1s ease; } .router-leave-to{ // 頁面完全顯示之后 opacity: 0; } </style> ~~~ >[success] ## 數據獲取 后期補充 >[success] ## 滾動行為 后期補充 >[success] ## 路由懶加載 后期補充 >[warning] ## 后期補充(該項后期刪除) 1. 看vue-router文檔 3. **對象模式** 的 **路由對象** 的 **props屬性**到底可不可以寫成動態的,個人理解: 3.1 布爾模式是【任意個數參數】在頁面中簡化params屬性 3.2 對象模式是【靜態的值】寫死的 3.3 函數模式是 【根據邏輯來判斷 **指定簡化的參數** 】改寫法比較靈活 4. 路由組件傳參的3種模式的應用場景 5. beforeEnter無法跳轉指定頁面,例如: ![](https://img.kancloud.cn/eb/06/eb0601bc89d4bb979dc95223876407bf_957x881.png) 6. 組件內的守衛到底是不是3個鉤子有沒有新出的鉤子 搜索 【后期】、【補充】,把沒寫的補充上
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看