三十分鐘學會使用vue-router搭建單頁應用(SPA)

1、什麼是單頁應用

單頁web應用(single page web application,SPA),就是隻有一張Web頁面的應用。單頁應用程序 (SPA) 是加載單個HTML 頁面並在用戶與應用程序交互時動態更新該頁面的Web應用程序。瀏覽器一開始會加載必需的HTML、CSS和JavaScript,全部的操做都在這張頁面上完成,都由JavaScript來控制。所以,對單頁應用來講模塊化的開發和設計顯得至關重要。javascript

2、單頁應用的優點和缺點

【1】優點html

  • 操做體驗流暢:媲美本地應用的感受,切換過程當中不會頻繁有被「打斷」的感受。由於界面框架都在本地,與服務端的通信基本只有數據,因此便於遷移,能夠用比較小的代價,遷移成桌面產品,或者各類移動端Hybrid產品。
  • 徹底的前端組件化:前端開發再也不以頁面爲單位,更多地採用組件化的思想,代碼結構和組織方式更加規範化,便於修改和調整;
  • API 共享:若是你的服務是多端的(瀏覽器端、Android、iOS、微信等),單頁應用的模式便於你在多個端共用 API,能夠顯著減小服務端的工做量。容易變化的 UI 部分都已經前置到了多端,只受到業務數據模型影響的 API,更容易穩定下來,便於提供更棒的服務;
  • 組件共享:在某些對性能體驗要求不高的場景,或者產品處於快速試錯階段,藉助於一些技術(HybridReact Native),能夠在多端共享組件,便於產品的快速迭代,節約資源。

【2】缺點前端

  • 首次加載大量資源:要在一個頁面上爲用戶提供產品的全部功能,在這個頁面加載的時候,首先要加載大量的靜態資源,這個加載時間相對比較長;不過能夠利用路由懶加載解決這個問題
  • 對搜索引擎不友好:由於界面的絕大部分都是動態生成的,因此搜索引擎很不容易索引它。
  • 開發難度相對較高:開發者的JavaScript技能必須過關,同時須要對組件化、設計模式有所認識,他所面對的再也不是一個簡單的頁面,而是一個運行在瀏覽器環境中的桌面軟件。

3、vue-router是什麼

vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,適合用於構建單頁面應用。vue的單頁面應用是基於路由和組件的,路由用於設定訪問路徑,並將路徑和組件映射起來。傳統的頁面應用,是用一些超連接來實現頁面切換和跳轉的。在vue-router單頁面應用中,則是路徑之間的切換,也就是組件的切換。路由模塊的本質 就是創建起url和組件之間的映射關係vue

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

4、安裝vue-router

npm install vue-router --save-dev複製代碼

5、配置和簡單使用vue-router

【1】在src文件夾下新增一個router文件夾,裏面添加一個index.js文件react

【2】在main.js文件中引入web

【3】router文件下的index.js配置vue-router

import Vue from 'vue'
import Router from 'vue-router'

// 引入page1和page2組件
import page1 from '@/components/page1'
import page2 from '@/components/page2'

Vue.use(Router)

export default new Router({
  // 定義路由,每一個路由應該映射一個組件,component對應引入的組件名
  routes: [
    {
      path: '/page1',
      name: 'page1',
      component: page1
    },
    {
      path: '/page2',
      name: 'page2',
      component: page2
    },
  ]
})複製代碼

【4】使用npm

咱們己經配置好了路由/page1和/page2,能夠在app.vue頁面使用這兩個路由編程

<template> <div id="app"> <!-- 一、使用router-link標籤來導航 二、經過傳入 `to` 屬性指定連接 三、<router-link> 默認會被渲染成一個 `<a>` 標籤 四、當<router-link>對應的路由匹配成功,將自動設置class屬性值爲.router-link-active --> <router-link to="/page1">page1</router-link> <!-- 經過路由設置的name值進行導航 --> <router-link :to="{name: 'page2'}">page2</router-link> <!-- 使用編程式導航 --> <span @click="gotoPage1">gotoPage1</span> <!-- 佔坑,路由匹配到的組件將渲染在這裏 --> <router-view /> </div> </template> <script> export default { methods: { gotoPage1() { // 編程式導航 this.$router.push('/page1') } }, } </script>複製代碼

【5】效果

6、this.$router 和 this.$route的區別

【1】router:是VueRouter的實例,至關於一個全局的路由器對象,裏面含有不少屬性和子對象,例如history對象,編程式路由導航可使用this.$router.push進行跳轉。

【2】route:至關於當前路由對象,能夠從裏面獲取name,path,params,query等

7、動態路由

【1】官方解釋

動態路徑參數,使用冒號 : 標記。當匹配到一個路由時,參數值會被設置到this.$route.params,能夠在每一個組件內使用。

你能夠在一個路由中設置多段「路徑參數」,對應的值都會設置到$route.params中。例如:

模式 匹配路徑 $route.params
/user/:username /user/evan

{ username: 'evan' }

/user/:username/post/:post_id /user/evan/post/123

{ username: 'evan', post_id: '123' }

【2】適用場景

好比商品詳情頁面,頁面結構都同樣,只是商品id的不一樣,因此這個時候就能夠用動態路由。

配置動態路由參數

// 配置路由
const router = new VueRouter({
  routes: [
    // 動態路徑參數 以冒號開頭
    { path: '/goods/:id', component: goods}
  ]
})複製代碼

goods組件

 <template> <div> 當前商品id爲:{{$route.params.id}} </div> </template>複製代碼

在瀏覽器地址欄中輸入/goods/123

8、嵌套路由

嵌套路由就是路由裏面嵌套他的子路由,子路由關鍵屬性children

每個子路由裏面能夠嵌套多個組件,子組件又有路由導航和路由容器

舉例:假設page頁面下包含home子組件和goods子組件

配置嵌套路由(在page路由下增長一個children屬性,配置home和goods兩個子組件路由)

export default new Router({
  // 定義路由,每一個路由應該映射一個組件,component對應引入的組件名
  routes: [
    {
      path: '/page',
      name: 'page',
      component: page,
      children: [{
        path: '/page/home',
        name: 'home',
        component: home,
      }, {
        path: '/page/goods',
        name: 'goods',
        component: goods,
      }]
    },
    {
      path: '/page2',
      name: 'page2',
      component: page2
    },
  ]
})
複製代碼

page組件配置

<template> <div> <p>page組件</p> <router-link to="/page/home">home</router-link> <router-link to="/page/goods">goods</router-link> <!-- 佔坑,匹配的子組件將渲染在這裏 --> <router-view></router-view> </div> </template>複製代碼

效果

9、編程式導航

【1】router.push

點擊 <router-link :to="..."> 等同於調用 this.$router.push(...)

在 Vue 實例內部,你能夠經過 $router訪問路由實例,所以你能夠調用 this.$router.push

聲明式 編程式
<router-link :to="..."> router.push(...)

$router.push(...)的參數能夠是一個字符串路徑,或者一個描述地址的對象。例如:

// 字符串
        router.push('home')

        // 對象
        router.push({ path: 'home' })

        // 命名的路由
        router.push({ name: 'user', params: { userId: '123' } })

        // 帶查詢參數,變成 /register?plan=private
        router.push({ path: 'register', query: { plan: 'private' } })

        // 注意:若是提供了path,params會被忽略。須要提供路由的name或手寫完整的帶有參數的path
        const userId = '123'
        router.push({ path: '/user', params: { userId }}) // -> /user params不生效
        router.push({ name: 'user', params: { userId }}) // -> /user/123 params生效
        router.push({ path: `/user/${userId}` }) // -> /user/123 params生效
        複製代碼

【2】router.replace

跟 router.push 很像,惟一的不一樣就是,它不會向 history 添加新記錄,而是跟它的方法名同樣 一一 替換掉當前的 history 記錄。

【3】router.go(n)

這個方法的參數是一個整數,意思是在 history 記錄中向前或者後退多少步,相似window.history.go(n)

// 在瀏覽器記錄中前進一步,等同於 history.forward() router.go(1) // 後退一步記錄,等同於 history.back() router.go(-1) // 前進 3 步記錄 router.go(3) // 後退 3 步記錄 router.go(-3)複製代碼

10、命名路由

就是在routers配置路由的時候加一個name屬性,經過name名稱來標識一個路由更加方便一些,特別是在嵌套路由path名稱特別長的時候

export default new Router({
  routes: [
    {
      path: '/page',
      name: 'page',
      component: page,
      children: [{
        path: '/page/home',
        name: 'home',
        component: home,
      }]
    },
  ]
})
複製代碼

如下四種方式均可以導航到/page/home路徑

 <router-link to="/page/home">home</router-link> <router-link :to="{name: home}">home</router-link>複製代碼
this.$router.push('/page/home')
    this.$router.push({name: home})複製代碼

11、命名視圖

簡單來講就是,給不一樣的router-view定義不一樣的名字,經過名字進行對應組件的渲染。若是router-view沒有設置名字,那麼默認爲default。

【1】適用場景

例如建立一個佈局,有 topNav(頂部導航)、sidebar (側導航) 和 main (主要內容) 三個視圖,這個時候命名視圖就派上用場了。

配置路由:根路由下定義了三個組件

index(主內容):映射在router-view 默認視圖上

topNav(頂部導航):映射在 router-view 的 name 爲 top 的視圖上

sideNav(側邊欄):映射在 router-view 的 name 爲 side 的視圖上

export default new Router({
  routes: [
    {
      path: '/',
      components: {
        default: Index,
        side: SideNav,
        top: TopNav,
      },
      children: [{
        path: '/home',
        component: Home,
      }, {
        path: '/goods',
        component: Goods,
      }]
    },
  ]
})複製代碼

App.vue文件(添加name屬性建立兩個命名視圖和一個default默認視圖)

 <router-view class="view one" name="top"></router-view> <router-view class="view two" name="side"></router-view> <router-view class="view three"></router-view>複製代碼

效果

12、重定向和別名

【1】重定向(redirect

/a的重定向是/b,當用戶訪問 /a 時,URL 將會被替換成 /b,而後導航到 /b 頁面

// 重定向目標能夠是一個path
    { path: '/a', component: A, redirect: '/b',  },

    // 重定向目標也能夠是一個命名的路由
    { path: '/a', component: A, redirect: {name: 'b'}},
    
    // 甚至是一個方法
    { path: '/a', component: A, redirect: to => {
      // 方法接收目標路由to做爲參數 to包含hash、params、query等屬性
      // return 重定向的字符串路徑/路徑對象
      return '/b'
    }}複製代碼

【2】別名(alias)

/a 的別名是 /b,意味着,當用戶訪問 /b 時,URL 會保持爲 /b,可是導航到 /a頁面,就像用戶訪問 /a 同樣。

routes: [
    { path: '/a', component: A, alias: '/b' }
  ]複製代碼

十3、vue-router模式

【1】hash (默認)

hash模式URL:http://www.abc.com/#/hello

hash即地址欄 URL 中的 # 符號,好比這個 URL:http://www.abc.com/#/hello,hash 的值爲 #/hello。它的特色在於hash 雖然出如今 URL 中,但不會被包括在 HTTP 請求中,對後端徹底沒有影響,所以改變 hash 不會從新加載頁面。

【2】history

history模式URL:http://www.abc.com/hello

有的時候出於強迫症,不能忍受模式下的URL上存在#符號,或者是出於業務需求,URL不能帶#號。這個時候要考慮採用vue-router的history模式,history模式的前端配置與上文大同小異,可是因爲history模式下URL 路徑的跳轉是vue-router利用h5的history API動態添加的,而手動刷新頁面會致使找不到路由從而產生404錯誤,所以還須要對服務端進行配置,將路由重定向到一級頁面

【3】模式配置

export default new Router({
  mode: 'history',
  routes: [...]
})複製代碼

十4、路由守衛

Vue - 路由守衛(路由的生命週期)

相關文章
相關標籤/搜索