# 🏅 Day 6 - NuxtLink 與 路由基礎配置 ## 今日學習目標 - 學習使用 NuxtLink 實作頁面導航 - 學習 Nuxt3 路由系統的基礎配置 ## NuxtLink 在 Vite 與 Vue CLI 可以使用 `<RouterLink>` 建立導航至其他頁面的路由連結。 ```html <!-- app.vue --> <template> <!-- 使用 RouterLink 導航至 首頁 頁面 ( 路徑 / ) --> <!-- 編譯成 : <a href="/">首頁</a>--> <RouterLink to="/">首頁</RouterLink> <!-- 使用 RouterLink 導航至 關於 頁面 ( 路徑 /about ) --> <!-- 編譯成 : <a href="/about">關於</a>--> <RouterLink to="/about">關於</RouterLink> </template> ``` 而在 Nuxt 則是會使用 `<NuxtLink>` 取代 `<RouterLink>` 元件實作頁面換頁的連結。 ```html <!-- app.vue --> <template> <h2>NuxtLink 基礎用法</h2> <ul class="list"> <li> <!-- 使用 NuxtLink 導航至 首頁 頁面 ( 路徑 / ) --> <!-- 編譯成 : <a href="/">首頁</a>--> <NuxtLink to="/">首頁</NuxtLink> </li> <li> <!-- 使用 NuxtLink 導航至 關於 頁面 ( 路徑 /about ) --> <!-- 編譯成 : <a href="/about">關於</a>--> <NuxtLink to="/about">關於</NuxtLink> </li> </ul> </template> ``` 它繼承了 `<RouterLink>` 的所有屬性並提供了額外的功能,例如: `external` 、`target` 屬性 …等。除此之外,與 `<RouterLink>` 相同, `<NuxtLink>` 也會被編譯為 HTML a 標籤。 以下將對 `<NuxtLink>` 的 `target` 與 `external` 屬性進行解說,其他屬性可以至 [官方文件](https://nuxt.com/docs/api/components/nuxt-link#nuxtlink) 查詢 ### target `target` 屬性用於控制連結點擊後的打開方式,其行為與值跟 HTML a 標籤的 [target 屬性](https://developer.mozilla.org/zh-TW/docs/Web/HTML/Element/a#target) 相同。 允許的值 : - **`_self`**(預設):在當前瀏覽器視窗打開連結。 - **`_blank`**:在新頁籤打開連結。 - **`_parent`**:在上一層父層視窗打開連結。 - **`_top`**:在最頂層父層視窗打開連結。 ```html <!-- app.vue --> <template> <ul class="list"> <li> <!-- 使用 target 屬性打開新頁籤 --> <NuxtLink to="/about" target="_blank" >關於 ( 使用 <code>target="_blank"</code> )</NuxtLink > </li> </ul> </template> ``` ### external `external`會將 `<NuxtLink>` 識別為外部連結,強制渲染成 HTML a 標籤而不是 `<RouterLink>`。 在設定 `external`屬性之後就不能再使用以下 “**繼承自 `<RouterLink>` 的所有屬性” 。這些屬性都依賴於 Vue Router** 管理狀態 , **但** `<NuxtLink>` **加入** `external`之後會被 Vue Router 忽略,狀態會改由瀏覽器管理 ,不會由 **Vue Router 管理 :** - exactActiveClass - replace - ariaCurrentValue - activeClass ```html <!-- app.vue --> <template> <ul class="list"> <li> <!-- 使用 external 屬性在 NuxtLink 中打開外部連結 --> <NuxtLink to="https://www.google.com/" external >google ( 外部連結 )</NuxtLink > </li> <li> <!-- 加入 external 之後 replace 、activeClass 會被忽略 --> <NuxtLink to="https://www.google.com/" external replace activeClass="active" > google ( 外部連結;<code>replace </code>、<code>activeClass</code> 屬性失效) </NuxtLink> </li> </ul> </template> <style scoped> .active { color: red; } </style> ``` ### 繼承自 RouterLink 的屬性 使用 `<NuxtLink>` 時,如果不同時使用 external 屬性,所有繼承自 RouterLink 的屬性,都會與在 Vue Router 中的使用方式完全一致。例如 `to`、`replace`、`activeClass`…等。 > When not using **`external`**, **`<NuxtLink>`** supports all Vue Router's [RouterLink props](https://router.vuejs.org/api/interfaces/RouterLinkProps.html) >-取自 [官方文件](https://nuxt.com/docs/api/components/nuxt-link#routerlink) ```html <!-- app.vue --> <template> <!-- 使用 to 屬性指定導航路徑 --> <NuxtLink to="/">首頁</NuxtLink> <!-- 使用 replace 屬性,不在瀏覽器留下新的歷史紀錄 --> <NuxtLink to="/about" replace>關於</NuxtLink> <!-- 使用 activeClass 屬性設定與目前路由配對的 CSS 樣式 --> <NuxtLink to="/contact" activeClass="active">聯絡</NuxtLink> </template> ``` ### 修改 linkActiveClass 與 linkExactActiveClass 的預設值 `<NuxtLink>` 的 `linkActiveClass`與 `linkExactActiveClass`屬性的運作與預設值和 Vue Router 相同,預設值分別為 '`router-link-active`’ 與 '`router-link-exact-active`’。 如果希望自定義這些屬性並調整應用到連結上的 class 名稱,可以參照 Nuxt3 [Router Options](https://nuxt.com/docs/guide/recipes/custom-routing#router-options) 的方法在 `nuxt.config.ts` 中使用 `router.options` 來設定 `linkActiveClass` 及`linkExactActiveClass`。 例如,如果希望路由 URL 與頁面連結相符時套用 `.active`class,可以進行以下設定 ```jsx // nuxt.config.ts export default defineNuxtConfig({ router: { options: { linkActiveClass: "active", linkExactActiveClass: "active", }, }, }); ``` 這樣一來,當頁面渲染後,符合條件的連結的 `<a>` 標籤將會套用 `.active` class: ```html <template> <!-- 當 URL 為 /about 時,實際在網頁上的內容會渲染成: --> <!-- <a href="/about" class="active">關於</a> --> <NuxtLink to="/about">關於</NuxtLink> </template> ``` ## 建立基礎路由結構 在 Day1 的題目練習中,我們有用指令在 pages 資料夾中新增 `index.vue` ,然後在 `app.vue` 以 `<NuxtPage />` 顯示新增的頁面。 ![image](https://hackmd.io/_uploads/Sklnuwhbkl.png) “在 pages 資料夾中新增 index.vue” 這一步其實就是在使用 Nuxt 提供的路由功能,透過 `pages/` 資料夾來為個每個頁面元件建立路由。並且在預設情境下,`pages/index.vue` 會對應到路由的 `/` 路徑。 ### Nuxt **pages 資料夾路由功能的特點** 在使用 pages 資料夾之後就不需要明確地在路由表定義路由物件格式與屬性,包括 `path` 、`component`、`name` 、`children` … 等。 嵌套式路由 ( 巢狀路由 ) 與動態路由也是一併使用資料夾管理,不需再額外寫路由表。 `pages`資料夾定義的結構,經編譯會生成對應的的路由結構。例如下圖左側的資料夾結構,經編譯後會產生右側路由表的結構。 ![image](https://hackmd.io/_uploads/Hk6nOw2Wkx.png) <br> > 今日學習的[範例 Code - 資料夾: day6-router-example](https://github.com/hexschool/nuxt-daily-tasks-2024) ## 題目 請 fork 這一份 [模板](https://github.com/jasonlu0525/nuxt3-live-question/tree/day6-router),完成以下條件 : - 建立前台首頁 ( `index.vue` ) 以及房型頁面 (`room.vue`) 。前台首頁對應的路由路徑為 `/` ,房型頁面的路由路徑為`/room`。 - 頁面上只需呈現純文字。前台首頁顯示 “首頁頁面” ,房型頁面 顯示“房型頁面” ```html <!-- 前台首頁 --> <template> <h1>首頁頁面</h1> </template> <!-- /room 房型頁面 --> <template> <h1>房型頁面</h1> </template> ``` - 將 app.vue 預設的 `<NuxtWelcome />` 歡迎改成可以顯示頁面的內容 。 - 在 `layouts/default.vue` 的 Layout 中已有載入 Bootstrap5 SCSS 及 Navbar 元件。需在 `layouts/default.vue` 的 Navbar 加入 `<NuxtLink>` 元件,實現切換頁面的功能。 - 修改路由預設的 `linkActiveClass` 和 `linkExactActiveClass` ,使 `<NuxtLink>` 匹配到路由的時候可以套用 Bootstrap5 的 `.active` class 。 ![image](https://hackmd.io/_uploads/r1uXtDnb1l.png) ## 回報流程 將答案上傳至 GitHub 並複製 GitHub repo 連結貼至底下回報就算完成了喔 ! 解答位置請參考下圖(需打開程式碼的部分觀看) ![](https://i.imgur.com/vftL5i0.png) <!-- 解答 : https://github.com/jasonlu0525/nuxt3-live-answer/tree/day6-router --> 回報區 --- | # | Discord | GitHub / 答案 | | --- | ----- | ----- | |1|LinaChen|[GitHub](https://github.com/Lina-SHU/nuxt3-live-question)| |2|Rocky|[GitHub](https://github.com/WuRocky/day-6-NuxtLink)| |3|kevihes|[GitHub](https://github.com/kevinhes/nuxt-daily-mission/tree/day6)| |4|Steven|[GitHub](https://github.com/y7516552/nuxt3-live-question/tree/day-6)| |5|dragon|[GitHub](https://github.com/peterlife0617/2024-nuxt-training-homework01/tree/feature/day06)| |6|MY|[GitHub](https://github.com/ahmomoz/nuxt3-live-question/tree/day6-router-hw)| |7|Stan|[GitHub](https://github.com/haoxiang16/nuxt3-live-question/tree/day6-router)| |8|松鼠|[GitHub](https://github.com/meishinro/dailyMissionSix)| |9|Ming|[GitHub](https://github.com/ming77712/2024-nuxt3-daily05)| |10|Jim Lin|[GitHub](https://github.com/junhoulin/Nuxt3-hw-day6)| |11|眼睛|[GitHub](https://github.com/Thrizzacode/nuxt3-live-question/tree/day6-router)| |12|Eden|[GitHub](https://github.com/1denx/NuxtDailyHw/tree/feature/day6-router)| | 13 | Tough life | [GitHub](https://github.com/hakuei0115/Nuxt_testing) | |14|NeiL|[GitHub](https://github.com/Neil10241126/nuxt-demo/tree/day6-router)| |15|wei_Rio|[GitHub](https://github.com/wei-1539/nuxtDaily6)| | 16 | Ariel | [GitHub](https://github.com/Ariel0508/nuxtday6) | | 17 | runweiting | [GitHub](https://github.com/runweiting/2024-NUXT-Task/tree/day6) | | 18 | hannahTW | [GitHub](https://github.com/hangineer/nuxt3-live-question/tree/day6-router) | | 19 | hsin yu | [GitHub](https://github.com/dogwantfly/nuxt3-daily-task-live-question/tree/day6-router) | | 20| barry1104 | [GitHub](https://github.com/barrychen1104/nuxt3-live-question/tree/day6-router) | | 21 | tanuki狸 | [GitHub](https://github.com/tanukili/Nuxt-2024-week01-2/tree/day6-router) | | 22 | 好了啦 | [GitHub](https://github.com/ZhangZJ0906/nuxt-live) | | 23 | 阿榮 | [GitHub](https://github.com/Peg-L/hex-nuxt3-live-question/tree/day6-router) | | 24 | Fabio20 | [GitHub](https://github.com/fabio7621/nuxt3-live-question-d2/tree/nuxt3-live-day6) | | 25 | 小蹦 | [GitHub](https://github.com/lgk559/hex-Nuxt3/tree/day6NuxtLink) | | 26 | Nielsen | [GitHub](https://github.com/asz8621/nuxt3-daily-task/tree/day6-router) | | 27 |YI | [GitHub](https://github.com/sming0305/NUXT-learn) | | 28 | 阿塔 | [GitHub](https://github.com/QuantumParrot/2024-Hexschool-Nuxt-Camp-Daily-Task) | | 29 | lidelin | [GitHub](https://github.com/Lide/nuxt3-live-question/tree/day6-router) | | 30 | Johnson | [GitHub](https://github.com/tttom3669/2024_hex_nuxt_daily/tree/day6-router) | | 31 | BB | [GitHub](https://github.com/wicebing/nuxt3-live-question/tree/day6-router) | <!-- 快速複製 | --- | ----- | [GitHub]() | -->