近距離觀察Vue路由

做者:Matt Maribojoc

翻譯:瘋狂的技術宅html

原文:https://vuejsdevelopers.com/2...前端

可以構建出色的單頁應用程序(SPA)是 Vue.js 最具備吸引力的功能之一。vue

SPA 很是好,由於它們不須要在每次更改路由時都去加載頁面。這就意味着一旦加載了所有內容,就能夠真正快速地對視圖進行切換,並提供出色的用戶體驗。程序員

若是你想要基於 Vue 去構建 SPA,則須要 Vue 路由。面試

在本教程中,我將介紹設置 Vue Router 的基礎知識,並研究一些更高級的技術,例如:vue-router

  • 動態路由匹配
  • 導航掛鉤(Navigation Hook)

Vue 路由是什麼?

Vue 路由有助於在瀏覽器的 URL 或歷史記錄與 Vue 組件之間創建連接,從而容許某些路徑渲染與之關聯的任何一個視圖。vue-cli

VueCore 小組成員 Eduardo San Martin Morote 在他的 VueConf Toronto演講中,對 Vue 路由背後的設計思想作了大量的分享。npm

Morote 討論了在靈活的路由(開發人員有更多的自主權,可是須要編寫更多的代碼)與死板的路由(開發人員擁有的自主權較少,可是路由涵蓋了更多的應用場景)之間進行權衡時,其背後的決策過程。編程

基於配置的 Vue 路由旨在爲開發人員提供用於常見應用場景的工具,並靈活應對獨特的問題。json

在繼續介紹一些更高級的 Vue 路由以前,先了解一下基礎知識。

Vue 路由的快速設置

首先是快速建立一個 Vue Router 的簡單例子。

雖然你能夠用 vue-cli 輕鬆添加 Vue 路由,可是我認爲你應該知道該怎樣本身進行操做。這樣纔可以真正瞭解Vue 路由的每一個細節。

首先用 npm install vue-router 把 Vue Router 添加到咱們的項目中。而後經過 src/main.js 文件將其包含在 Vue 實例中。

import Vue from 'vue'
import App from './App.vue'
import router from './router'// loads from src/router/index.js
    
new Vue({    
  router,
  render: h => h(App),
}).$mount('#app')

完成全部設置後,開始建立路由。

在 src 內,建立一個 src/router 文件夾,其中的 index.js 文件包含如下內容。

import Vue from 'vue'
import VueRouter from  'vue-router'
import Home from '../views/Home.vue'
import Profile from '../views/Profile.vue'

Vue.use(VueRouter);

const routes = [
  {
    path: "/",
    name: "home",
    component: Home
  },
  {
    path: '/profile',
    name: 'profile',
    component: Profile
  }
]

const router = new VueRouter({
  mode: 'history',
  routes
})

export default router

這個代碼段用了兩個路由組件匹配來初始化 Vue Router。我不會在這裏介紹 Home 和 Profile 組件的詳細信息,你只須要假設它們分別輸出 「home」 和 「profile」 就好了。

顯示路由視圖

前面已經設置了 Vue 路由,可是尚未查看效果的方式。

這時就須要 <router-view> 元素髮揮做用了。從本質上講,router-view 元素爲 Vue Router 提供了一個位置,用來渲染當前 URL 被解析後對應的組件。

對於這個例子,咱們將其放在 App.vue 根組件中。再添加一些連接,以即可以在兩個路由之間切換。 Vue Router 使用稱爲 <router-link> 的特殊連接元素,這些元素的 to 屬性可以映射到組件。

<template>
  <div id="app">
    <router-link to='/'>Home</router-link>
    <router-link to='/profile'>Profile</router-link>
    <router-view  />
  </div>
</template>

運行咱們的應用時,應該可以看到 home 組件渲染。若是單擊路由連接元素,那麼內容將會被更改,同時 URL 也會更改!

下面深刻了解 Vue Router 的更多細節。

以編程方式更改路由

在前面的示例中,咱們使用 <router-link> 在不一樣的路線之間導航。從本質上講,這些等效於 Vue Router 的<a> 標籤(實際上,它們能夠編譯爲 <a> 標籤)。

可是另外一種更改路由的方法是用 router.push 方法以編程方式進行導航。與使用 <router-link> 相似,router.push 接受經過使用其路徑或名稱的字符串或對象映射到一個路由。

this.$router.push({ path: '/profile' })
// OR
this.$router.push({ name: 'profile' })

使用此方法傳遞 URL 參數或查詢也很容易。只須要添加一個 paramsquery 參數便可。

this.$router.push({ 
        path: '/profile', 
        params: { username: 'helloworld' }, 
        query: { source:  'tutorial' } 
    })

歷史記錄模式和哈希模式之間的區別

Vue 路由的 URL 有兩種模式:歷史記錄和哈希模式。

  • 哈希模式(默認)——使用 URL 哈希來模擬 URL,例如 mypage.com/#profile
  • 歷史記錄——看起來像一個典型的 URL,並使用 history.pushState 來避免頁面被從新加載;例如mypage.com/profile

咱們的路由用了歷史記錄模式,由於我我的喜歡標準 URL 外觀。

處理動態路由

你能夠把 URL 模式與組件進行匹配,而沒必要對每一個可能的路徑進行硬編碼。這對於配置文章頁面、我的資料頁面和其餘能夠動態建立或刪除的內容很是有用。

用冒號 : 在 Vue 路由中定義動態路徑。例如,若是咱們要動態匹配文章頁面,則路由應以下所示。

{
  path:  '/post/:postID',
  name:  'post',
  component:  ArticlePage
}

這個路由會把全部遵循 /post/:postID 模式的 URL 導航到相同的 ArticlePage.vue 組件。

若是想要在組件內部獲取 postID,有兩種方法能夠實現。

  1. 咱們的 postID 能夠經過 $route.params 對象在 ArticlePage 中訪問
  2. 咱們能夠把文章 ID 做爲 prop 傳遞給你的組件。

我推薦使用第二種方法,由於它可使你構建更多的不依賴於特定 URL 格式的可重用組件。

只需在路線中添加 props:true 便可。添加該屬性後,咱們的動態路由應以下所示。

{
  path:  '/post/:postID',
  props: true,
  name:  'post',
  component:  ArticlePage
}

在組件中,必須確保在聲明 prop 時要與在路由中聲明的名稱相同。

<template>
  <div>
    {{ postID }}
  </div>
</template>
<script>
export  default {
  props: {
    postID:  String
  }
}
</script>

在更完整的項目中,咱們一般會採用路由傳遞的 prop 值,並經過 API 調用來加載相應的內容。可是一旦能夠訪問組件內部的 prop 時,就可使用它進行任何操做。

導航守護簡介

導航守護是 Vue Router 中更高級的內容之一。它們是路由過程當中的 Hook,可以讓你重定向、取消或修改導航。

導航守護有三種類型:

  1. 全局守護
  2. 特定路由的守護
  3. 在組件中的守護

此外,守護能夠接受三個參數:

  • to:咱們要到達的那個路由
  • from:要離開的路由
  • next:用於解決 Hook 的函數;根據傳遞給下一個方法的參數,咱們的路由將處理不一樣的導航
  • next(false):停止導航,不離開 from 路由

    • next('/ home'):把咱們的導航重定向到指定的路由
  • next():若是沒有參數,則會簡單地將其移至下一個 Hook;確認導航沒有剩餘的Hook

1. 全局守護

全局守護的措施主要有兩種:router.beforeEach()router.afterEach() 分別在導航解析以前和以後運行。

讓咱們來看一個例子。在此方法中,首先檢查用戶是否有權訪問某個頁面,若是沒有訪問權,將會阻止路由解析。請注意,每次 Hook 運行時僅調用一次。

router.beforeEach( (to, next, from) => {
  if (to.path === '/profile') {
    if (!hasAccess(to.path)) { // just some arbitrary conditional
        next(false) // deny access to this page
    } else {
        next() // keep moving on to next hook
    }
  } else {
    next() // keep moving on to next hook
  }
})

2. 特定於路由的守護

當咱們在 Vue Router 中聲明路由時,還能夠添加一個 beforeEnter 函數,其功能相似於全局 beforeEach 路由,可是它能夠包含特定於路由的邏輯。

{
  path:  '/post/:postID',
  props:  true,
  name:  'post',
  component:  ArticlePage,
  beforeEnter: (to, from, next) => {
    // some logic here
  }
}

3.在組件中的守護

更具體地說,咱們能夠在組件的 options 對象中插入導航守護,總共有三種:

  • beforeRouteEnter (to, from, next):在確認此路由以前調用;該組件還沒有建立。
  • beforeRouteUpdate (to, from, next) :在切換路由時調用;但新路由也能夠肯定此組件。
  • beforeRouteLeave(to, from, next):當離開這個組件時被調用

須要注意的是,在確認導航以前和實際建立組件以前,將會調用 beforeRouteEnter。此時咱們尚未訪問this

爲了解決這個問題,beforeRouteEnter 容許咱們將回調傳給下一個方法,該方法將在組件實際建立後當即執行。

beforeRouteEnter (to, from, next) {
  next((vm) => {
    // vm = 'this'
    console.log(vm)
  })
}

總結

但願本文可以幫你你學習一些基本和高級的 Vue 路由技術。

探索一個靈活但易用的路由所涉及的設計思路很是頗有趣。在聽過 Morote 的演講以後,我認爲後續可能還會有更多的改進!

前端刷題神器

掃碼進入前端面試星球🌍,解鎖刷題神器,還能夠獲取800+道前端面試題一線常見面試高頻考點

173382ede7319973.gif


本文首發微信公衆號:前端先鋒

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

歡迎繼續閱讀本專欄其它高贊文章:


相關文章
相關標籤/搜索