從頭開始學習vue-router

1、前言

要學習vue-router就要先知道這裏的路由是什麼?爲何咱們不能像原來同樣直接用標籤編寫連接哪?vue-router如何使用?常見路由操做有哪些?等等這些問題,就是本篇要探討的主要問題。html

2、vue-router是什麼

這裏的路由並非指咱們平時所說的硬件路由器,這裏的路由就是SPA(單頁應用)的路徑管理器。再通俗的說,vue-router就是WebApp的連接路徑管理系統。 vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,適合用於構建單頁面應用。vue的單頁面應用是基於路由和組件的,路由用於設定訪問路徑,並將路徑和組件映射起來。傳統的頁面應用,是用一些超連接來實現頁面切換和跳轉的。在vue-router單頁面應用中,則是路徑之間的切換,也就是組件的切換。路由模塊的本質 就是創建起url和頁面之間的映射關係前端

至於咱們爲啥不能用a標籤,這是由於用Vue作的都是單頁應用(當你的項目準備打包時,運行npm run build時,就會生成dist文件夾,這裏面只有靜態資源和一個index.html頁面),因此你寫的標籤是不起做用的,你必須使用vue-router來進行管理。vue

3、vue-router實現原理

SPA(single page application):單一頁面應用程序,只有一個完整的頁面;它在加載頁面時,不會加載整個頁面,而是隻更新某個指定的容器中內容。單頁面應用(SPA)的核心之一是: 更新視圖而不從新請求頁面;vue-router在實現單頁面前端路由時,提供了兩種方式:Hash模式和History模式;根據mode參數來決定採用哪種方式。html5

一、Hash模式:

vue-router 默認 hash 模式 —— 使用 URL 的 hash 來模擬一個完整的 URL,因而當 URL 改變時,頁面不會從新加載。 hash(#)是URL 的錨點,表明的是網頁中的一個位置,單單改變#後的部分,瀏覽器只會滾動到相應位置,不會從新加載網頁,也就是說hash 出如今 URL 中,但不會被包含在 http 請求中,對後端徹底沒有影響,所以改變 hash 不會從新加載頁面;同時每一次改變#後的部分,都會在瀏覽器的訪問歷史中增長一個記錄,使用」後退」按鈕,就能夠回到上一個位置;因此說Hash模式經過錨點值的改變,根據不一樣的值,渲染指定DOM位置的不一樣數據。hash 模式的原理是 onhashchange 事件(監測hash值變化),能夠在 window 對象上監聽這個事件git

二、History模式:

因爲hash模式會在url中自帶#,若是不想要很醜的 hash,咱們能夠用路由的 history 模式,只須要在配置路由規則時,加入"mode: 'history'",這種模式充分利用了html5 history interface 中新增的 pushState() 和 replaceState() 方法。這兩個方法應用於瀏覽器記錄棧,在當前已有的 back、forward、go 基礎之上,它們提供了對歷史記錄修改的功能。只是當它們執行修改時,雖然改變了當前的 URL ,但瀏覽器不會當即向後端發送請求github

//main.js文件中
const router = new VueRouter({
  mode: 'history',
  routes: [...]
})
複製代碼

當你使用 history 模式時,URL 就像正常的 url,例如 yoursite.com/user/id,比較好… 不過這種模式要玩好,還須要後臺配置支持。由於咱們的應用是個單頁客戶端應用,若是後臺沒有正確的配置,當用戶在瀏覽器直接訪問 oursite.com/user/id 就會返回 404,這就很差看了。 因此呢,你要在服務端增長一個覆蓋全部狀況的候選資源:若是 URL 匹配不到任何靜態資源,則應該返回同一個 index.html 頁面,這個頁面就是你 app 依賴的頁面。web

export const routes = [ 
  {path: "/", name: "homeLink", component:Home}
  {path: "/register", name: "registerLink", component: Register},
  {path: "/login", name: "loginLink", component: Login},
  {path: "*", redirect: "/"}]
複製代碼

此處就設置若是URL輸入錯誤或者是URL 匹配不到任何靜態資源,就自動跳到到Home頁面vue-router

三、使用路由模塊來實現頁面跳轉的方式

  • 方式1:直接修改地址欄npm

  • 方式2:this.$router.push(‘路由地址’)編程

  • 方式3:<router-link to="路由地址"></router-link>

4、vue-router使用方式

1:下載 npm i vue-router -S 2:在main.js中引入 import VueRouter from 'vue-router'; 3:安裝插件Vue.use(VueRouter); 4:建立路由對象並配置路由規則 let router = new VueRouter({routes:[{path:'/home',component:Home}]}); 5:將其路由對象傳遞給Vue的實例,options中加入 router:router 6:在app.vue中留坑 <router-view></router-view>

具體實現請看以下代碼:

//main.js文件中引入
import Vue from 'vue';
import VueRouter from 'vue-router';
//主體
import App from './components/app.vue';
import Home from './components/home.vue'
//安裝插件
Vue.use(VueRouter); //掛載屬性
//建立路由對象並配置路由規則
let router = new VueRouter({
    routes: [
        //一個個對象
        { path: '/home', component: Home }
    ]
});
//new Vue 啓動
new Vue({
    el: '#app',
    //讓vue知道咱們的路由規則
    router: router, //能夠簡寫router
    render: c => c(App),
})
複製代碼

最後記得在在app.vue中「留坑」

//app.vue中
<template>
    <div>
        <!-- 留坑,很是重要 -->
        <router-view></router-view>
    </div>
</template>
<script>
    export default {
        data(){
            return {}
        }
    }
</script>
複製代碼

5、 vue-router參數傳遞

聲明式的導航<router-link :to="...">和編程式的導航router.push(...)均可以傳參,本文主要介紹前者的傳參方法,一樣的規則也適用於編程式的導航。

1.用name傳遞參數

在路由文件src/router/index.js裏配置name屬性

routes: [
    {
      path: '/',
      name: 'Hello',
      component: Hello
    }
]
複製代碼

模板裏(src/App.vue)用$route.name來接收 好比:<p>{{ $route.name}}</p>

2 經過<router-link> 標籤中的to傳參

這種傳參方法的基本語法:

<router-link :to="{name:xxx,params:{key:value}}">valueString</router-link>
複製代碼

好比先在src/App.vue文件中

<router-link :to="{name:'hi1',params:{username:'jspang',id:'555'}}">Hi頁面1</router-link>
複製代碼

而後把src/router/index.js文件裏給hi1配置的路由起個name,就叫hi1.

{path:'/hi1',name:'hi1',component:Hi1}
複製代碼

最後在模板裏(src/components/Hi1.vue)用$route.params.username進行接收.

{{$route.params.username}}-{{$route.params.id}}
複製代碼

3 利用url傳遞參數----在配置文件裏以冒號的形式設置參數。

咱們在/src/router/index.js文件裏配置路由

{
    path:'/params/:newsId/:newsTitle',
    component:Params
}
複製代碼

咱們須要傳遞參數是新聞ID(newsId)和新聞標題(newsTitle).因此咱們在路由配置文件裏制定了這兩個值。

在src/components目錄下創建咱們params.vue組件,也能夠說是頁面。咱們在頁面裏輸出了url傳遞的的新聞ID和新聞標題。

<template>
    <div>
        <h2>{{ msg }}</h2>
        <p>新聞ID:{{ $route.params.newsId}}</p>
        <p>新聞標題:{{ $route.params.newsTitle}}</p>
    </div>
</template>
<script>
export default {
  name: 'params',
  data () {
    return {
      msg: 'params page'
    }
  }
}
</script>
複製代碼

在App.vue文件里加入咱們的<router-view>標籤。這時候咱們能夠直接利用url傳值了

<router-link to="/params/198/jspang website is very good">params</router-link>

4. 使用path來匹配路由,而後經過query來傳遞參數

<router-link :to="{ name:'Query',query: { queryId: status }}" >
     router-link跳轉Query
</router-link>

複製代碼

對應路由配置:

{
     path: '/query',
     name: 'Query',
     component: Query
   }
複製代碼

因而咱們能夠獲取參數:

this.$route.query.queryId
複製代碼

6、vue-router配置子路由(二級路由)

實際生活中的應用界面,一般由多層嵌套的組件組合而成。一樣地,URL中各段動態路徑也按某種結構對應嵌套的各層組件,例如:

如何實現下圖效果(H1頁面和H2頁面嵌套在主頁中)

1.首先用<router-link>標籤增長了兩個新的導航連接

<router-link :to="{name:'HelloWorld'}">主頁</router-link>
<router-link :to="{name:'H1'}">H1頁面</router-link>
<router-link :to="{name:'H2'}">H2頁面</router-link>
複製代碼

2.在HelloWorld.vue加入<router-view>標籤,給子模板提供插入位置

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <router-view></router-view>
  </div>
</template>
複製代碼

3.在components目錄下新建兩個組件模板 H1.vue 和 H2.vue 二者內容相似,如下是H1.vue頁面內容:

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        msg: 'I am H1 page,Welcome to H1'
      }
    }
  }
</script>
複製代碼
  1. 修改router/index.js代碼,子路由的寫法是在原有的路由配置下加入children字段。
routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld,
      children: [{path: '/h1', name: 'H1', component: H1},//子路由的<router-view>必須在HelloWorld.vue中出現
        {path: '/h2', name: 'H2', component: H2}
      ]
    }
  ]
複製代碼

7、單頁面多路由區域操做

在一個頁面裏咱們有兩個以上<router-view>區域,咱們經過配置路由的js文件,來操做這些區域的內容

1.App.vue文件,在<router-view>下面新寫了兩行<router-view>標籤,並加入了些CSS樣式

<template>
  <div id="app">
    <img src="./assets/logo.png">
       <router-link :to="{name:'HelloWorld'}"><h1>H1</h1></router-link>
       <router-link :to="{name:'H1'}"><h1>H2</h1></router-link>
    <router-view></router-view>
    <router-view name="left" style="float:left;width:50%;background-color:#ccc;height:300px;"/>
    <router-view name="right" style="float:right;width:50%;background-color:yellowgreen;height:300px;"/>
  </div>
</template>
複製代碼

2.須要在路由裏配置這三個區域,配置主要是在components字段裏進行

export default new Router({
    routes: [
      {
        path: '/',
        name: 'HelloWorld',
        components: {default: HelloWorld,
          left:H1,//顯示H1組件內容'I am H1 page,Welcome to H1'
          right:H2//顯示H2組件內容'I am H2 page,Welcome to H2'
        }
      },
      {
        path: '/h1',
        name: 'H1',
        components: {default: HelloWorld,
          left:H2,//顯示H2組件內容
          right:H1//顯示H1組件內容
        }
      }
    ]
  })
複製代碼

上邊的代碼咱們編寫了兩個路徑,一個是默認的‘/’,另外一個是‘/Hi’.在兩個路徑下的components裏面,咱們對三個區域都定義了顯示內容。最後頁面展現以下圖:

八.$route$router 的區別

咱們先將這二者console.log打印出來:

$route 是「路由信息對象」,包括 path,params,hash,query,fullPath,matched,name 等路由信息參數。

$route.path 字符串,對應當前路由的路徑,老是解析爲絕對路徑,如 "/order"。

$route.params 一個 key/value 對象,包含了 動態片斷 和 全匹配片斷, 若是沒有路由參數,就是一個空對象。

$route.query 一個 key/value 對象,表示 URL 查詢參數。 例如,對於路徑 /foo?user=1,則有 $route.query.user爲1, 若是沒有查詢參數,則是個空對象。

$route.hash 當前路由的 hash 值 (不帶 #) ,若是沒有 hash 值,則爲空字符串。

$route.fullPath 完成解析後的 URL,包含查詢參數和 hash 的完整路徑。

$route.matched 數組,包含當前匹配的路徑中所包含的全部片斷所對應的配置參數對象。

$route.name 當前路徑名字

$router 是「路由實例」對象,即便用 new VueRouter建立的實例,包括了路由的跳轉方法,鉤子函數等。

$router常見跳轉方法:

<button @click="goToMenu" class="btn btn-success">Let's order!</button> ..... <script> export default{ methods:{ goToMenu(){ this.$router.go(-1)//跳轉到上一次瀏覽的頁面 this.$router.replace('/menu')//指定跳轉的地址 this.$router.replace({name:'menuLink'})//指定跳轉路由的名字下 this.$router.push('/menu')//經過push進行跳轉 this.$router.push({name:'menuLink'})//經過push進行跳轉路由的名字下 } } } </script> 複製代碼

$router.push$router.replace的區別

  • 使用push方法的跳轉會向 history 棧添加一個新的記錄,當咱們點擊瀏覽器的返回按鈕時能夠看到以前的頁面。
  • 使用replace方法不會向 history 添加新記錄,而是替換掉當前的 history 記錄,即當replace跳轉到的網頁後,‘後退’按鈕不能查看以前的頁面。

9、 如何設置404頁面

用戶會常常輸錯頁面,當用戶輸錯頁面時,咱們但願給他一個友好的提示頁面,這個頁面就是咱們常說的404頁面。vue-router也爲咱們提供了這樣的機制。

  1. 設置咱們的路由配置文件(/src/router/index.js)
{
   path:'*',
   component:Error
}
複製代碼

這裏的path:'*'就是輸入地址不匹配時,自動顯示出Error.vue的文件內容

  1. 在/src/components/文件夾下新建一個Error.vue的文件。簡單輸入一些有關錯誤頁面的內容。
<template>
    <div>
        <h2>{{ msg }}</h2>
    </div>
</template>
<script>
export default {
  data () {
    return {
      msg: 'Error:404'
    }
  }
}
</script>
複製代碼

此時咱們隨意輸入一個錯誤的地址時,便會自動跳轉到404頁面

參考文章

相關文章
相關標籤/搜索