# 4-3 <router-link>
建立路由連結
前面我們曾經短暫介紹過 <router-link>
可以用來建立路由連結,
但它所提供的功能可不只是產生超連結而已,否則我們直接寫 <a>
標籤就好了。
這個小節就為讀者們介紹 <router-link>
的各種常見用法。
先從最基本的用法快速講起:
<router-link to="/">Go to Home</router-link>
<router-link to="/about">Go to About</router-link>
<!-- 實際的渲染結果 -->
<a href="/">Go to Home</a>
<a href="/about">Go to About</a>
2
3
4
5
6
像這樣 <router-link>
加上 to
屬性,可以快速建立一個超連結,
並與我們前一個小節介紹過的路由高度整合,達到無需重整即可讀取對應的 Vue.js 元件,並同時更新 URL 網址的效果。
# to
屬性
這個 to
屬性,除了可以直接給一段純文字的路徑外,也可以是這樣的形式:
<!-- 與 v-bind 綁定,省略 path -->
<router-link :to="'/home'">Home</router-link>
<!-- 指定 path,作用與前面一樣 -->
<router-link :to="{ path: '/home' }">Home</router-link>
<!-- 搭配具名路由 -->
<router-link :to="{ name: 'user', params: { userId: '123' }}">User</router-link>
<!-- 搭配 query 參數, 編譯後的結果會出現在 queryString: `/register?plan=private` -->
<router-link :to="{ path: '/register', query: { plan: 'private' }}">
Register
</router-link>
2
3
4
5
6
7
8
9
10
11
12
13
# replace
屬性
若我們不希望在瀏覽器留下 URL 的歷史紀錄,可以在 <router-link>
加上 replace
屬性:
<router-link to="/abc" replace></router-link>
這樣在背後執行時會呼叫 Vue Router 的 router.replace()
(預設為 router.push()
) 來替換網址,實際效果類似 JavaScript 的 location.replace()
那樣,更新頁面之後不會在瀏覽器留下 URL 紀錄,所以我們也無法透過「上一頁」或「下一頁」的按鈕來切換狀態。
# active-class
與目前路由配對的樣式
當目前的 URL 與頁面上的連結相符的時候,過去我們可能會需要自行判斷 active
的 CSS Class,
<template>
<ul>
<li><a :class="{ 'active': location.pathname === '/' }" href="/">Home</a></li>
<li><a :class="{ 'active': location.pathname === '/list' }" href="/list">List</a></li>
<li><a :class="{ 'active': location.pathname === '/about' }" href="/about">About</a></li>
</ul>
</template>
2
3
4
5
6
7
類似這樣的做法來處理網頁連結是否要加上 active
的 CSS。
但是當我們使用 Vue Router 的 <router-link>
之後,就可以利用 router-link-active
與 router-link-exact-active
這兩組 Class 名稱來處理:
<template>
<ul>
<li><router-link to="/">Home</router-link></li>
<li><router-link to="/list">List</router-link></li>
<li><router-link to="/about">About</router-link></li>
</ul>
</template>
2
3
4
5
6
7
完全不用對任何東西加工即可使用。
而 router-link-active
與 router-link-exact-active
的差別在於 router-link-active
是模糊比對,router-link-exact-active
是準確比對。
當我們今天 URL 在根目錄 「/
」 的時候:
<router-link to="/">Home</router-link>
實際在網頁上的內容會渲染成:
<a href="/" class="router-link-active router-link-exact-active">Home</a>
另外,若我們目前的位置在 /list/123
:
<router-link to="/list">List</router-link>
實際在網頁上的內容會渲染成:
<a href="/list" class="router-link-active">List</a>
因為我們目前的 URL 在 /list
下層的 /list/123
,所以對應的 List 連結只會有 router-link-active
這個 Class,而不會出現 router-link-exact-active
。
# <router-link>
與 v-slot
<router-link>
元件也可以與我們在第二章所介紹過的插槽 - Scoped Slots 搭配使用。
<router-link
to="/about"
custom
v-slot="{ href, route, navigate, isActive, isExactActive }">
<NavLink :active="isActive" :href="href" @click="navigate">
{{ route.fullPath }}
</NavLink>
</router-link>
2
3
4
5
6
7
8
<router-link>
所提供的 v-slot
可以有這些屬性:
href
: 解析後的網址,提供給<a>
的href
目標字串。route
: 回傳完整的 Route 物件。navigate
: 觸發路由的事件函式,必要時會阻止此事件執行。isActive
: 若回傳值為true
,則表示目前路由的 URL 與目標相同,可用來取代預設的router-link-active
。isExactActive
: 若回傳值為true
,則表示目前路由的 URL 與目標「完全」相同,可用來取代預設的router-link-exact-active
。
舉例來說,若我們希望將原本的 <router-link>
所渲染出來的 <a>
改為 <button>
,那麼可以這樣做:
<router-link to="/about" custom v-slot="{ navigate }">
<button @click="navigate" role="link">About Us</button>
</router-link>
2
3
渲染的結果就會是:
<button role="link">About Us</button>
這裡有幾個地方需要注意的是,若不希望外層被 <a>
標籤包覆, <router-link>
需要加上 custom
屬性。
另外,若未加上 @click="navigate"
處理對應的點擊事件,這個 <button>
在點擊時就不會有 URL 轉頁的效果。
小提醒
若你的 <a>
標籤有使用 target="_blank"
,則 navigate
會被忽略。
# 透過 router.push()
/ router.replace()
操作路由
在前面的範例裡,我們都透過 <router-link :to="...">
來渲染出連結操作網站的路由,
如果我們希望透過程式來做到網站的導頁,就需要透過 Vue Router 所提供的 router.push()
與 router.replace()
方法了。
router.push()
使用的方式與我們操作網址的概念大同小異,
// 透過字串指定 URL
router.push('/users/eduardo')
// 透過物件與 path 指定
router.push({ path: '/users/eduardo' })
// 與具名路由、params 搭配
router.push({ name: 'user', params: { username: 'eduardo' } })
// 以 query 指定目標的 query string
router.push({ path: '/register', query: { plan: 'private' } })
// 搭配 hash, 執行後的結果為 /about#team
router.push({ path: '/about', hash: '#team' })
2
3
4
5
6
7
8
9
10
11
12
13
14
router.replace()
方法使用的方式與 router.push()
完全一樣,唯一的差別是 router.replace()
不會在瀏覽器裡留下紀錄。
小提醒
說到瀏覽器紀錄,Vue Router 也提供 router.go()
方法來模擬 window.history.go()
,例如:
// 到下一頁 (或下一個路由紀錄),等同 router.forward()
router.go(1)
// 到前一頁 (或前一個路由紀錄),等同 router.back()
router.go(-1)
2
3
4
5