【前端 Vue】07 - Vue-router

1. 后端路由階段

早期的網(wǎng)站開發(fā)整個HTML頁面是由服務器來渲染的。服務器直接生產(chǎn)渲染好對應的HTML頁面, 返回給客戶端進行展示。

1.1 但是, 一個網(wǎng)站, 這么多頁面服務器如何處理呢?

  1. 一個頁面有自己對應的網(wǎng)址, 也就是URL。

  2. URL會發(fā)送到服務器, 服務器會通過正則對該URL進行匹配, 并且最后交給一個Controller進行處理。

  3. Controller進行各種處理, 最終生成HTML或者數(shù)據(jù), 返回給前端。

  4. 這就完成了一個IO操作。

上面的這種操作, 就是后端路由,當我們頁面中需要請求不同的路徑內容時, 交給服務器來進行處理, 服務器渲染好整個頁面, 并且將頁面返回給客戶端,這種情況下渲染好的頁面, 不需要單獨加載任何的jscss, 可以直接交給瀏覽器展示, 這樣也有利于SEO的優(yōu)化。

1.2 后端路由的缺點:

  1. 一種情況是整個頁面的模塊由后端人員來編寫和維護的;

  2. 另一種情況是前端開發(fā)人員如果要開發(fā)頁面, 需要通過PHPJava等語言來編寫頁面代碼;

  3. 而且通常情況下HTML代碼和數(shù)據(jù)以及對應的邏輯會混在一起, 編寫和維護都是非常糟糕的事情。

2. 前端路由階段

2.1 前后端分離階段

  1. 隨著Ajax的出現(xiàn), 有了前后端分離的開發(fā)模式。

  2. 后端只提供API來返回數(shù)據(jù), 前端通過Ajax獲取數(shù)據(jù), 并且可以通過JavaScript將數(shù)據(jù)渲染到頁面中。

  3. 這樣做最大的優(yōu)點就是前后端責任的清晰, 后端專注于數(shù)據(jù)上, 前端專注于交互和可視化上。

  4. 并且當移動端(iOS/Android)出現(xiàn)后, 后端不需要進行任何處理, 依然使用之前的一套API即可。

2.2 單頁面富應用階段

  1. 其實SPA最主要的特點就是在前后端分離的基礎上加了一層前端路由。

  2. 也就是前端來維護一套路由規(guī)則。

3. URL的hash 模式 和 HTML5 的 history 模式

3.1 URL的hash模式

  1. URLhash也就是錨點(#), 本質上是改變window.locationhref屬性;我們可以通過直接賦值location.hash來改變href, 但是頁面不發(fā)生刷新。
location.hash改變location的href屬性
地址欄是這樣的

3.2 HTML5的history模式

  1. history對象的pushState方法傳遞三個參數(shù),第一個參數(shù)是一個對象。第二個參數(shù)是title , 第三個參數(shù)是路徑。
pushState方法
地址欄是這樣的
  1. history模式的replaceState方法:替換路徑,不能通過返回箭頭返回。
history的replaceState方法
  1. history模式的go方法:到某個索引的路徑下:
history.go(-1) // 表示后退一步  和 history.back() 類似 

history.go(1) // 表示前進一步 和 history.forward() 類似

4. Vue-Router的安裝配置

  1. Vue-router是 Vue.js官方的路由插件,它和

4.1 安裝 Vue-Router

  1. 安裝為一個運行時依賴:
npm install vue-router --save 
  1. 創(chuàng)建一個router文件夾,并在文件中創(chuàng)建一個index.js文件。

  2. index.js文件中引入 VueRouter對象和 Vue對象。

import VueRouter from 'vue-router';
import Vue from 'vue';
  1. 通過Vue.use(傳入插件)安裝該插件,任何Vue的插件都要使用 Vue.use進行安裝。
Vue.use(VueRouter);
  1. 創(chuàng)建 VueRouter對象實例 , 注意這里是 routes 而不是 routers 重要重要重要
// 路由數(shù)組
const routes = [];

// 2. 創(chuàng)建VueRouter對象
const router = new VueRouter({
  // 配置組件之間的映射關系
  // 對象屬性的簡寫
  routes
});
  1. 導出 VueRouter對象實例:
export default router;
  1. main.js中引入并使用 router
在`main.js`中引入并使用 `router`

4.2 配置路由的映射關系

  1. components文件夾下創(chuàng)建 HomeAbout組件。
  1. router/index.js下配置路由映射關系 。
配置路由映射關系
  1. 使用 Vue 中注冊的全局組件 router-linkrouter-view實現(xiàn)頁面跳轉和渲染。
 <div id="app">
    <!-- router-link是Vue中注冊的全局組件 -->
    <router-link to="/home">首頁</router-link>
    <router-link to="/about">關于</router-link>
    <router-view></router-view>
  </div>
  1. <router-link>: 該標簽是一個vue-router中已經(jīng)內置的組件, 它會被渲染成一個<a>標簽。

  2. <router-view>: 該標簽會根據(jù)當前的路徑, 動態(tài)渲染出不同的組件。

  3. 默認顯示首頁:/home,將進入頁面時將頁面重定向到 Home頁面

// 路由數(shù)組
const routes = [
  {
    path: '/',
    /* 將路徑重定向到home */
    redirect: '/home'
  },
  {
    path: '/home',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    component: About
  }
]

4.3 修改路由的模式為 history

  1. 默認情況下,路徑改變使用的是URLhash,如果希望使用 HTML5history模式可以進行如下的修改。
修改路由的模式為history
// 2. 創(chuàng)建VueRouter對象
const router = new VueRouter({
  // 配置組件之間的映射關系
  // 對象屬性的簡寫 但是這個屬性必須交 routes
  routes,
  mode:'history'
});

4.4 router-link 的其他屬性

router-link 標簽的 tag 屬性
  1. 可以 通過 tag設置router-link使用什么標簽來進行渲染。
<!-- router-link是Vue中注冊的全局組件 -->
    <router-link tag="button" to="/home">首頁</router-link>
    <router-link tag="button" to="/about">關于</router-link>
使用button標簽進行渲染
router-link 標簽的 replace 屬性
  1. replace屬性設置之之后通過該標簽跳轉的路徑,不能通過瀏覽器的后退鍵返回。replace不會留下history記錄, 所以指定replace的情況下, 后退鍵返回不能返回到上一個頁面中。這就說明vue-router默認使用的是 historypushState。
<!-- router-link是Vue中注冊的全局組件 -->
    <router-link tag="button" to="/home" replace>首頁</router-link>
    <router-link tag="button" to="/about" replace>關于</router-link>
不能通過瀏覽器的后退鍵返回
router-link 標簽的 active-class 屬性
  1. 默認情況下當點擊某個標簽,該標簽被激活之后,在其中會添加一個class ,router-link-active??梢酝ㄟ^該class設置激活樣式。
 .router-link-active {
    color: #f00;
  }
按鈕被激活
  1. class的名稱是可以被修改的,此時就需要在標簽中 使用active-class屬性對class的名稱進行修改。
    <!-- router-link是Vue中注冊的全局組件 -->
    <router-link tag="button" to="/home" replace active-class="active">首頁</router-link>
    <router-link tag="button" to="/about" replace active-class="active">關于</router-link>
.active {
    color: #00f;
  }
使用active-class修改class的名稱
router/index.js文件的router對象中使用linkActiveClass屬性統(tǒng)一修改樣式名稱
統(tǒng)一對link激活樣式名稱進行修改
統(tǒng)一修改了link的樣式名稱
將link的激活樣式名稱修改為linkActive

4.5 通過代碼實現(xiàn)路由的跳轉

  1. 在頁面中定義兩個按鈕實現(xiàn)路由的跳轉:利用 vue內置的 $routerpushreplace方法實現(xiàn)跳轉。
    <!-- 通過代碼實現(xiàn)路由的跳轉  -->
    <button @click="btnClickHome">首頁</button>
    <button @click="btnClickAbout">關于</button>
      /**
       * 跳轉到 首頁
       */
      btnClickHome() {
        // this.$router.push('/home');
        this.$router.replace('/home'); // 跳轉之后不能通過瀏覽器的后退按鈕返回
      },

      /**
       * 實現(xiàn)跳轉到關于
       */
      btnClickAbout() {
        // this.$router.push('/about');
        this.$router.replace('/about'); // 跳轉之后不能通過瀏覽器的后退按鈕返回
      }

5. vue-router 動態(tài)路由的使用

  1. 創(chuàng)建一個 User組件并在 router/index.js中配置路由:

// 路由數(shù)組
const routes = [
  {
    path: '/',
    /* 將路徑重定向到home */
    redirect: '/home'
  },
  {
    path: '/home',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    component: About
  },
  {
    path: '/user/:userId',
    component: User
  }
];
配置User組件的路由
  1. APP.vue中使用 router-link配置路由實現(xiàn)跳轉:在配置時一并傳遞參數(shù)。
     <!-- 實現(xiàn)動態(tài)路由 -->
    <router-link to="/home">首頁</router-link>
    <router-link to="/about">關于</router-link>
    <!-- 在此使用動態(tài)路由 使用 v-bind 動態(tài)綁定 -->
    <router-link :to="`/user/` + userId">用戶</router-link>
使用v-bind動態(tài)綁定userId
  1. 在跳轉到User組件之后,在User頁面獲取到路徑中的userId參數(shù):這里需要通過一個$route的屬性獲取。使用 $route.params.userId獲取。但是這里的userId是與路由配置中的userId一一對應的。
 <div>
    <h2>我是User組件</h2>
    <!-- 獲取到路徑中傳遞的用戶名 的兩種方式-->
    <!-- 1. 直接在Mustache語法中寫 -->
    <h2>{{$route.params.userId}} 您好!</h2>
    <!-- 2. 通過計算屬性的方式 -->
    <h2>{{userId}} 您好!</h2>
  </div>
computed: {
      userId() {
        return this.$route.params.userId
      }
    }
通過$route.params.userId獲取路徑中userId參數(shù)

6. vue-router 打包文件的解析

打包之后的dist文件夾下的JS

7. 路由的懶加載

  1. 路由懶加載的官方解釋:首先, 我們知道路由中通常會定義很多不同的頁面,這個頁面最后被打包在哪里呢? 一般情況下, 是放在一個js文件中,但是, 頁面這么多放在一個js文件中, 必然會造成這個頁面非常的大,
    如果我們一次性從服務器請求下來這個頁面, 可能需要花費一定的時間, 甚至用戶的電腦上還出現(xiàn)了短暫空白的情況。

  2. 路由懶加載做了什么? 答: 路由懶加載的主要作用就是將路由對應的組件打包成一個個的js代碼塊。只有在這個路由被訪問到的時候, 才加載對應的組件。

配置路由懶加載前后

7.2 各種路由懶加載的配置方式

  1. 方式一: 結合Vue的異步組件和Webpack的代碼分析
const Home = resolve => { require.ensure(['../components/Home.vue'], () => { resolve(require('../components/Home.vue')) })};
  1. 方式二:AMD寫法
const About = resolve => require(['../components/About.vue'], resolve);
  1. 方式三: 在ES6中, 我們可以有更加簡單的寫法來組織Vue異步組件和Webpack的代碼分割
const Home = () => import('../components/Home.vue')

8. 認識路由的嵌套

理解路由的嵌套

8.1 嵌套路由配置案例

  1. 創(chuàng)建一個 HomeMessageHomeNews組件。
<template>
  <div>
    <ul>
      <li>消息1</li>
      <li>消息2</li>
      <li>消息3</li>
      <li>消息4</li>
    </ul>
  </div>
</template>

<script>
    export default {
        name: "home-message"
    }
</script>

<style scoped>

</style>
<template>
  <div>
    <ul>
      <li>新聞1</li>
      <li>新聞2</li>
      <li>新聞3</li>
      <li>新聞4</li>
    </ul>
  </div>
</template>

<script>
    export default {
        name: "home-news"
    }
</script>

<style scoped>
</style>
  1. 配置嵌套路由 :
/* 使用懶加載的方式加載組件 */
const Home = () => import('../components/Home')
const HomeNews = () => import('../components/HomeNews')
const HomeMessage = () => import('../components/HomeMessage')
const About = () => import('../components/About')
const User = () => import('../components/User')

// 1. 通過Vue.use(傳入插件)安裝該插件,任何Vue的插件都要使用 Vue.use進行安裝
Vue.use(VueRouter);

// 路由數(shù)組
const routes = [
  {
    path: '/',
    /* 將路徑重定向到home */
    redirect: '/home'
  },
  {
    path: '/home',
    name: 'Home',
    component: Home,
    /* 配置路由的嵌套 */
    children:[
      /* 配置默認顯示首頁的時候一并顯示消息 */
      {
        path:'/',
        redirect:'news'
      }
      ,
      {
        /* 注意這里沒有 斜杠 / 這里是不能有 斜杠的  */
        path:'news',
        component:HomeNews
      },
      {
        path:'message',
        component:HomeMessage
      }
    ]
  },
  {
    path: '/about',
    component: About
  },
  {
    path: '/user/:userId',
    component: User
  }
];
嵌套路由的詳細配置
  1. 因為這兩個組件需要在 Home組件中切換顯示,所以還需在Home組件中使用router-linkrouter-view進行配置。
<template>
  <div>
    <h2>我是Home組件</h2>
    <router-link to="/home/news">新聞</router-link>
    <router-link to="/home/message">消息</router-link>
    <router-view></router-view>
  </div>
</template>
在Home組件中使用 router-link 和 router-view進行配置

9. vue-router 參數(shù)傳遞

9.1 參數(shù)傳遞的方式一 user/:userId

使用在路由中配置的方式傳遞參數(shù)

9.2 參數(shù)傳遞的方式二 query參數(shù)對象傳遞案例

  1. 創(chuàng)建一個新的組件 Profile
<template>
  <div>
    <h2>我是Profile組件</h2>
  </div>
</template>

<script>
  export default {
    name: "profile"
  }
</script>

<style scoped>

</style>
  1. 為組件配置路由 :
為Profile組件配置路由
  1. 使用 router-link的方式實現(xiàn)路由的跳轉并傳遞query參數(shù)對象。
使用 `router-link`的方式實現(xiàn)路由的跳轉并傳遞`query`參數(shù)對象
  1. 使用觸發(fā)事件的方式實現(xiàn)路由的跳轉:通過this.$router.push(``)的方式實現(xiàn)路由跳轉。
使用觸發(fā)事件的方式實現(xiàn)路由的跳轉

10. vue-router 和 vue-route 是由區(qū)別的

  1. $routerVueRouter實例,想要導航到不同URL,則使用$router.push方法。

  2. $route為當前router跳轉對象里面可以獲取name、path、query、params等。

vue-router和 vue-route是由區(qū)別的

11. 導航守衛(wèi)

1.有時可能需要在跳轉過程之間做一些新的操作。就可以使用導航守衛(wèi)監(jiān)聽跳轉過程。

  1. URL組成: URL= scheme(協(xié)議)://host(主機):port(端口)/path(路徑)?query(查詢)#fragment(片段);

11.1 當頁面跳轉的時候如果需要改變 title 該如何做?

  1. 網(wǎng)頁標題是通過<title>來顯示的, 但是SPA只有一個固定的HTML, 切換不同的頁面時, 標題并不會改變。

  2. 但是我們可以通過JavaScript來修改<title>的內容 window.document.title = '新的標題'。

  1. 那么在Vue 項目中, 在哪里修改? 什么時候修改比較合適呢?
使用導航守衛(wèi)在路由跳轉前進行修改頁面 title操作
  1. 使用 router實例對象的beforeEach 方法前置守衛(wèi)函數(shù),函數(shù)中傳遞一個鉤子函數(shù),鉤子函數(shù)需要 3 個參數(shù)。to , from ,next。需要向下執(zhí)行就需要調用 next()。

  2. 在執(zhí)行next()之前將 title進行修改。但是動態(tài)的 title從哪里來呢?

在每一個route中定義一個meta元數(shù)據(jù)存放title

11.2 導航守衛(wèi)的分類

  1. 全局路由守衛(wèi);

  2. 路由獨享守衛(wèi);

  3. 組件內守衛(wèi)。

  4. 參考。

12. vue-router 的 keep-alive

  1. keep-alive 是一個標簽,是一個保持組件為活躍狀態(tài),不會被頻繁的創(chuàng)建和頻繁的銷毀。
保持組件為活躍狀態(tài)不會被頻繁的創(chuàng)建和銷毀

12.1 利用 keep-alive 和 activated 、beforeRouteLeave 導航守衛(wèi)實現(xiàn)記住上一個頁面的選擇案例

keep-alive實現(xiàn)記住上一次
默認home路徑
  1. router-view標簽外面包裹了keep-alive標簽之后 activated方法就會有效:在該方法中實現(xiàn)路由的跳轉。
在`router-view`標簽外面包裹了`keep-alive`標簽
  1. 當離開當前的組件之前記錄一下當前的路徑path。
    在beforeRouteLeave方法中就是離開組件之前記住上次的路徑
只有使用 keep-alive標簽包裹的組件使用 activated 和 deactived 才是有效的。

12.2 keep-alive的其他屬性

keep-aliveVue 內置的一個組件,可以使被包含的組件保留狀態(tài),或避免重新渲染。
  1. include : 字符串或正則表達,只有匹配的組件會被緩存;

  2. exclude : 字符串或正則表達式,任何匹配的組件都不會被緩存;

    <!-- 但是中間不要隨便加空格 -->
    <keep-alive exclude="profile,User">
      <router-view></router-view>
    </keep-alive>
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容