從頭開始學習vue-router

一、前言


要學習vue-router就要知道這里的路由是什么?為什么我們不能像原來一樣直接用標簽寫鏈接?vue-router如何使用?常見路由操作有哪些?

二、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-router實現原理


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

1、Hash模式:

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

2、History模式:

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

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

當你使用 history 模式時,URL 就像正常的 url,例如 http://yoursite.com/user/id,比較好看!
不過這種模式要玩好,還需要后臺配置支持。因為我們的應用是個單頁客戶端應用,如果后臺沒有正確的配置,當用戶在瀏覽器直接訪問 http://oursite.com/user/id 就會返回 404,這就不好看了。
所以呢,你要在服務端增加一個覆蓋所有情況的候選資源:如果 URL 匹配不到任何靜態資源,則應該返回同一個 index.html 頁面,這個頁面就是你 app 依賴的頁面。

 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頁面

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

方式1:直接修改地址欄
方式2:this.$router.push(‘路由地址’)
方式3:<router-link to="路由地址"></router-link>

四、vue-router核心要點


1.vue-router參數傳遞

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

①用name傳遞參數

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

routes: [
    {
      path: '/',
      name: 'Hello',
      component: Hello
    }
]

模板里(src/App.vue)用$route.name來接收

②通過<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}}

③vue-router 利用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>

④使用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

2.單頁面多路由區域操作

在一個頁面里我們有2個以上<router-view>區域,我們通過配置路由的js文件,來操作這些區域的內容

①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>
②需要在路由里配置這三個區域,配置主要是在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里面,我們對三個區域都定義了顯示內容。

3.嵌套路由

routes: [
   {
     path: '/',
     name: 'HelloWorld',
     component: HelloWorld,
     children: [{path: '/h1', name: 'H1', component: H1},//子路由的<router-view>必須在HelloWorld.vue中出現
       {path: '/h2', name: 'H2', component: H2}
     ]
   }
 ]

4. route 和router的區別

$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創建的實例,包括了路由的跳轉方法,鉤子函數等。

5. 404頁面的設置

用戶會經常輸錯頁面,當用戶輸錯頁面時,我們希望給他一個友好的提示頁面,這個頁面就是我們常說的404頁面。vue-router也為我們提供了這樣的機制。
①設置我們的路由配置文件(/src/router/index.js)

{
   path:'*',
   component:Error
}

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

②在/src/components/文件夾下新建一個Error.vue的文件。簡單輸入一些有關錯誤頁面的內容。

<template>
    <div>
        <h2>{{ msg }}</h2>
    </div>
</template>
<script>
export default {
  data () {
    return {
      msg: 'Error:404'
    }
  }
}
</script>

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

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容