大家應該也發現到了,目前點選 Navbar 項目並沒有任何反應;但是點選公版中的 Home 和 About 時:
之前有介紹過 App.vue 是整個專案的核心主件,並且會在此處進行切換路由元件及渲染相應頁面,因此仔細觀察 App.vue,我們可以發現與兩個 router 相關的關鍵字—— <router-link>
和 <router-view>
元件。
<div id="app">
<Navbar />
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view />
</div>
<router-link>
:導航<router-link>
是個提供使用者在具有路由功能的應用程式中,能透過點擊事件觸發導航功能的元件,利用 prop to
導向指定的目標路由,渲染結果預設為 <a>
標籤。(aria-current 為無障礙網頁屬性)
<!-- template -->
<router-link to="/">Home</router-link>
<!-- render -->
<a href="/" class="router-link-active" aria-current="page">Home</a>
如欲指定渲染結果的標籤,則可使用 tag
變更指定,且仍然保有監聽點擊事件而觸發路由切換的效果。
<!-- template -->
<router-link to="/" tag="li">Home</router-link>
<!-- render -->
<li class="router-link-active">Home</li>
prop to
為必填項目,其所指定的路徑透過觸發點擊事件後傳遞給 router.push()
方法進行路由切換。該值可以是字串或描述目標位址的路由物件:
字串型別
<router-link to="/">Home</router-link>
綁定路由物件
<router-link :to="{ path: '/' }">Home</router-link>
<router-link :to="{ name: 'About' }">About</router-link>
<router-view>
:路由出口<router-view>
則是個功能元件,其隨著 <router-link>
的路徑切換,負責顯示出匹配當前路徑的元件內容。以 App.vue 為例,當路徑切換至「/about」時,<router-view>
就會將畫面內容在其範圍內渲染成當前路徑 About.vue 的元件內容。
<router-view>
唯一的 prop 就是 name
,用來為自己命名,有了指定名稱之後,<router-view>
就只會顯示對應的元件內容。例如在同一個頁面中需要同時顯示兩個區塊——主要區塊和側邊欄,此時就可以在同一個路由中設置 components
物件(特別注意 component 的結尾要加上代表複數的「s」),接著在 components
裡各別設定 <router-view>
所對應的元件,name
作為 key(若無指定名稱則預設為 default),元件名稱作為 value。
<router-view class="view main" />
<router-view class="view sidebar" name="aside" />
const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: Main,
aside: Sidebar,
}
}
]
})
接著來釐清這三個相似名詞的含義:
由於 router 實例在 main.js 掛載到 Vue 實例中,所以在每個元件裡都可以使用下列屬性:
this.$route
:代表當前的路由物件(The Route Object),其包含一些唯讀屬性解析該路由的相關信息,例如路徑(path)、路由參數(params)、查詢參數(query)等。this.$router
:代表 router 實例,其包含的設置更多,如建構選項(Construction Options)、實例屬性(Properties)及方法(Methods)。兩種屬性各司其職,但以下方式則會指向同一個路由物件:
this.$router.currentRoute
=this.$route
試著在 <script> 寫個 console 觀察結果就知道了!
mounted() {
console.log("router: ", this.$router.currentRoute);
console.log("route: ", this.$route);
},
了解 router 規則之後,現在來改寫我們的 Navbar 路由吧!
首先,四個 navItem 分別要在 router/index.js 中新增路由配置,以及在 views 資料夾中新增對應的 .vue 檔案,才能在路徑切換時找到元件渲染內容。
原始結構
<b-navbar-nav
class="my_navbar_item"
v-for="navItem in navList"
:key="navItem.id"
>
<b-nav-item href="#">{{ navItem.item }}</b-nav-item>
</b-navbar-nav>
data() {
return {
navList: [
{ id: 1, item: "全部書單" },
{ id: 2, item: "七折區" },
{ id: 3, item: "五折區" },
{ id: 4, item: "iT邦幫忙鐵人賽系列書" },
],
};
},
改寫方式:在 data
中新增 name,以供 to
綁定。
data() {
return {
navList: [
{ id: 1, item: "全部書單", name: "All" },
{ id: 2, item: "七折區", name: "Discount30" },
{ id: 3, item: "五折區", name: "Discount50" },
{ id: 4, item: "iT邦幫忙鐵人賽系列書", name: "Ithelp" },
],
};
},
方法1:透過 router 實例方法 router.push()
維持 BootstrapVue 元件結構,在 <b-nav-item> 上新增 click 事件,於觸發點擊事件時使用 router.push()
方法導向指定路由位址。
<b-navbar-nav
class="my_navbar_item"
v-for="navItem in navList"
:key="navItem.id"
>
<b-nav-item href="#" @click="$router.push({ name: navItem.name })">
{{ navItem.item }}
</b-nav-item>
</b-navbar-nav>
順手一起改寫 <b-navbar-brand>,使得點擊「天瓏書單」時導向首頁位址。
<b-navbar-brand href="#" @click="$router.push('/')">
天瓏書單
</b-navbar-brand>
方法2:使用 <router-link>
元件
因為 <b-nav-item> 已是巢狀結構中的最子層,所以在此處直接用 <router-link>
元件來取代,另加上原本在 <b-nav-item> 上的 class="nav-link"
以渲染出 BootstrapVue 元件樣式。
<b-navbar-nav
class="my_navbar_item"
v-for="navItem in navList"
:key="navItem.id"
>
<router-link :to="{ name: navItem.name }" class="nav-link">
{{ navItem.item }}
</router-link>
</b-navbar-nav>
試試看點擊每個 Navbar 項目是否都能成功跳轉了呢~