vue-router — 用vue做web單頁應用

vue-router基本介紹

Juo Penguin
7 min readAug 7, 2020

基本組件

<router-link>: 連結到其他路由

<router-view>: 渲染與路由配對的組件

routes: 路由設定配對components放這邊

“name”: 在RouteConfig中(詳見以下routes的部分),來為路由命名(推薦使用!!)

巢狀view: 同一個路由下渲染子組件

router物件常用方法: router.push(), router.go(), router.replace()直接透過function操作路由

router物件

this.$router: 在組件中取得router物件

this.route: 在組件中取得route物件

<router-link />

用於跳轉連結,預設情況等同於使用router.push()

LinkTo { 
name?: string //命名的route
path?: string //相對路徑
params?: object //動態參數
query?: object //查詢
}
主要propsprops {
to: string | LinkTo
replace: boolean
append: boolean
}

router-link各種使用範例

//基本使用
<router-link
:to="'/users'"
>
Users
</router-link>
// 對應到/user:userId的route
<router-link
:to="{ path: 'user', params: { userId: 1 }}"
>
User
</router-link>
// 等同 /search?mode=all
<router-link
:to="{ path: 'search', query: { mode: 'all' }}"
>
Search All
</router-link>

<router-view />

符合路徑的組件會動態渲染於此

props { 
name?: string
// 用於渲染巢狀組件.對應到components中符合property name的組件
}

使用範例

// 路由
routes: [ { name: 'profile', component: Profile } ]
// 目前路徑 /profile
<template>
<router-view />
</template>
//等同於
<template>
<Profile />
</template>

name

name使用範例,在符合該路徑底下的components的property name如果跟name符合,就會被渲染

routes = [{
name: 'user',
component: User,
components: { intro: Intro, },
}]
// 目前路徑 /user
<template>
<router-view />
<router-view name="intro" />
</template>
//等同於
<template>
<User />
<Intro />
</template>

routes

路由設定

routes: RouteConfig[] // 僅列主要config
RouteConfig {
path: stirng // 唯一必要,設定此route的相對路徑
component?: Component // 要渲染的component
name?: string // 命名此route
components?: { [name: string]: Component } // 給有name的router-view
props?: boolean | object | function //設定是否傳遞props及靜態props
children?: RouteConfig[] // 巢狀routes可設定於此
}

路由 & 組件完整使用範例

$router相關methods

$router.push(location, onComplete?, onAbort?)

router.push({ name: 'user', })
//等同於
<router-link :to="{ name: 'user' }"/>

$router.go(num: number)

router.go(1) 
//往前一個history紀錄 等同於 history.forward()
router.go(-1)
//往後一個history紀錄(上一頁) 等同於 router.back() 或history.back()

$router.replace(location, onComplete?, onAbort?)

router.replace({ name: 'home', })
//等同於
<router-link :to="{ name: 'home' }" replace />

$router

vue全域router object,可於component中取得使用

const BackButton = Vue.component({ 
methods: {
handleBack() { this.$router.back(); },
},
template: '<button @click="handleBack">Back</button>'
})

$route

vue全域router object,可於component中取得使用

可取得目前路徑的path, params, query…等

const User = Vue.component({ 
computed: {
userId() { return this.$route.params.id }
}
})

個人常用自訂組件

<LinkButton />

連結按鈕

進階用法

路由保護

例如,在路由移動前先驗證,可以使用:

router.beforeEach((to, from, next) => { //… next(); })

to(Route): 下一個路由

from(Route): 來自哪個路由

next( function(route?: RouteConfig) {} ): 被呼叫才會移動至下個路由,因此可以先用from, to做比對再決定是否到下一個路由

const router = new VueRouter({ //... })// 在到下一個路由之前先做相關驗證
router.beforeEach((to, from, next) => {
const isAuth = //...
if(to.name === 'signedPage' && !isAuth)
next({ name: '/login' })
else
next()
})

其他完整使用

搭配meta使用

<transition>

因為router-view本身是動態渲染的組件,所以也可以使用transition做為外面的wrapper搭配,跟<component :is="">的使用一樣

<transition name="fade">
<router-view />
</transition>

--

--

Juo Penguin
Juo Penguin

Written by Juo Penguin

不挑食的雜食者,近期的目標是瘦10公斤。

No responses yet