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

一、什么是單頁應(yīng)用

單頁web應(yīng)用(single page web application,SPA),就是只有一張Web頁面的應(yīng)用。單頁應(yīng)用程序 (SPA) 是加載單個HTML 頁面并在用戶與應(yīng)用程序交互時動態(tài)更新該頁面的Web應(yīng)用程序。瀏覽器一開始會加載必需的HTML、CSS和JavaScript,所有的操作都在這張頁面上完成,都由JavaScript來控制。因此,對單頁應(yīng)用來說模塊化的開發(fā)和設(shè)計顯得相當重要。

二、單頁應(yīng)用的優(yōu)勢和缺點

【1】優(yōu)勢

  • ** 操作體驗流暢:**媲美本地應(yīng)用的感覺,切換過程中不會頻繁有被“打斷”的感覺。因為界面框架都在本地,與服務(wù)端的通訊基本只有數(shù)據(jù),所以便于遷移,可以用比較小的代價,遷移成桌面產(chǎn)品,或者各種移動端Hybrid產(chǎn)品。
  • ** 完全的前端組件化:**前端開發(fā)不再以頁面為單位,更多地采用組件化的思想,代碼結(jié)構(gòu)和組織方式更加規(guī)范化,便于修改和調(diào)整;
  • ** API 共享:**如果你的服務(wù)是多端的(瀏覽器端、Android、iOS、微信等),單頁應(yīng)用的模式便于你在多個端共用 API,可以顯著減少服務(wù)端的工作量。容易變化的 UI 部分都已經(jīng)前置到了多端,只受到業(yè)務(wù)數(shù)據(jù)模型影響的 API,更容易穩(wěn)定下來,便于提供更棒的服務(wù);
  • 組件共享:在某些對性能體驗要求不高的場景,或者產(chǎn)品處于快速試錯階段,借助于一些技術(shù)(Hybrid、React Native),可以在多端共享組件,便于產(chǎn)品的快速迭代,節(jié)約資源。

【2】缺點

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

三、vue-router是什么

    vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,適合用于構(gòu)建單頁面應(yīng)用。vue的單頁面應(yīng)用是基于路由和組件的,路由用于設(shè)定訪問路徑,并將路徑和組件映射起來。傳統(tǒng)的頁面應(yīng)用,是用一些超鏈接來實現(xiàn)頁面切換和跳轉(zhuǎn)的。在vue-router單頁面應(yīng)用中,則是路徑之間的切換,也就是組件的切換。**路由模塊的本質(zhì) 就是建立起url和組件之間的映射關(guān)系**。

    至于我們?yōu)樯恫荒苡胊標簽,這是因為用Vue做的都是單頁應(yīng)用(當你的項目npm run build 打包后,就會生成dist文件夾,這里面只有靜態(tài)資源和一個index.html頁面),所以你寫的<a></a>標簽跳轉(zhuǎn)頁面是不起作用的,你必須使用vue-router來進行管理。

四、安裝vue-router

npm install vue-router -mages.ages/2334.oorient/strip) 

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

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

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

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

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({
  // 定義路由,每個路由應(yīng)該映射一個組件,component對應(yīng)引入的組件名
  routes: [
    {
      path: '/page1',
      name: 'page1',
      component: page1
    },
    {
      path: '/page2',
      name: 'page2',
      component: page2
    },
  ]
})

【4】使用

我們己經(jīng)配置好了路由/page1和/page2,可以在app.vue頁面使用這兩個路由

<template>
  <div id="app">
    <!-- 
      1、使用router-link標簽來導航 
      2、通過傳入 `to` 屬性指定鏈接
      3、<router-link> 默認會被渲染成一個 `<a>` 標簽
      4、當<router-link>對應(yīng)的路由匹配成功,將自動設(shè)置class屬性值為.router-link-active
    -->
    <router-link to="/page1">page1</router-link>

    <!-- 通過路由設(shè)置的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】效果

六、this.router 和 this.route的區(qū)別

【1】router:是VueRouter的實例,相當于一個全局的路由器對象,里面含有很多屬性和子對象,例如history對象,編程式路由導航可以使用this.$router.push進行跳轉(zhuǎn)。

【2】route:相當于當前路由對象,可以從里面獲取name,path,params,query等

七、動態(tài)路由

【1】官方解釋

動態(tài)路徑參數(shù),使用冒號 : 標記。當匹配到一個路由時,參數(shù)值會被設(shè)置到this.$route.params,可以在每個組件內(nèi)使用。

你可以在一個路由中設(shè)置多段“路徑參數(shù)”,對應(yīng)的值都會設(shè)置到$route.params中。

【2】適用場景

比如商品詳情頁面,頁面結(jié)構(gòu)都一樣,只是商品id的不同,所以這個時候就可以用動態(tài)路由。

配置動態(tài)路由參數(shù)

// 配置路由
const router = new VueRouter({
  routes: [
    // 動態(tài)路徑參數(shù) 以冒號開頭
    { path: '/goods/:id', component: goods}
  ]
})

goods組件

  <template>
    <div>
      當前商品id為:{{$route.params.id}}
    </div>
  </template>

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

八、嵌套路由

嵌套路由就是路由里面嵌套他的子路由,子路由關(guān)鍵屬性children

每一個子路由里面可以嵌套多個組件,子組件又有路由導航和路由容器

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

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

export default new Router({
  // 定義路由,每個路由應(yīng)該映射一個組件,component對應(yīng)引入的組件名
  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>

效果

九、編程式導航

【1】router.push

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

在 Vue 實例內(nèi)部,你可以通過 router訪問路由實例,因此你可以調(diào)用 this.router.push

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

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

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

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

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

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

        // 注意:如果提供了path,params會被忽略。需要提供路由的name或手寫完整的帶有參數(shù)的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)

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

// 在瀏覽器記錄中前進一步,等同于 history.forward()
router.go(1)

// 后退一步記錄,等同于 history.back()
router.go(-1)

// 前進 3 步記錄
router.go(3)

// 后退 3 步記錄
router.go(-3)

十、命名路由

就是在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})

十一、命名視圖

簡單來說就是,給不同的router-view定義不同的名字,通過名字進行對應(yīng)組件的渲染。如果router-view沒有設(shè)置名字,那么默認為default。

【1】適用場景

例如創(chuàng)建一個布局,有 topNav(頂部導航)、sidebar (側(cè)導航) 和 main (主要內(nèi)容) 三個視圖,這個時候命名視圖就派上用場了。

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

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

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

sideNav(側(cè)邊欄):映射在 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屬性創(chuàng)建兩個命名視圖和一個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>

效果

十二、重定向和別名

【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作為參數(shù) to包含hash、params、query等屬性
      // return 重定向的字符串路徑/路徑對象
      return '/b'
    }}

【2】別名(alias)

/a 的別名是 /b,意味著,當用戶訪問 /b 時,URL 會保持為 /b,但是導航到 /a頁面,就像用戶訪問 /a 一樣。

  routes: [
    { path: '/a', component: A, alias: '/b' }
  ]

十三、vue-router模式

【1】hash (默認)

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

hash即地址欄 URL 中的 # 符號,比如這個 URL:http://www.abc.com/#/hello,hash 的值為 #/hello。它的特點在于hash 雖然出現(xiàn)在 URL 中,但不會被包括在 HTTP 請求中,對后端完全沒有影響,因此改變 hash 不會重新加載頁面。

【2】history

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

有的時候出于強迫癥,不能忍受模式下的URL上存在#符號,或者是出于業(yè)務(wù)需求,URL不能帶#號。這個時候要考慮采用vue-router的history模式,history模式的前端配置與上文大同小異,但是由于history模式下URL 路徑的跳轉(zhuǎn)是vue-router利用h5的history API動態(tài)添加的,而手動刷新頁面會導致找不到路由從而產(chǎn)生404錯誤,因此還需要對服務(wù)端進行配置,將路由重定向到一級頁面

【3】模式配置

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

十四、路由守衛(wèi)

Vue - 路由守衛(wèi)(路由的生命周期)

文章每周持續(xù)更新,可以微信搜索「 前端大集錦 」第一時間閱讀,回復(fù)【視頻】【書籍】領(lǐng)取200G視頻資料和30本PDF書籍資料

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容