iT邦幫忙

2021 iThome 鐵人賽

DAY 11
0
Modern Web

Vue.js 什麼意思系列 第 11

Day 11:Router 怎麼繞-router-link、router-view

大家應該也發現到了,目前點選 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,
      }
    }
  ]
})

route、routes、router 分清楚

接著來釐清這三個相似名詞的含義:

  • route:單一路由,一個路由只對應到一個元件
  • routes:由多個單一路由(route)組合而成的路由陣列,在 router/index.js 中定義路由配置後,將配置參數傳入創建的 router 實例中
  • router:路由管理器,在 main.js 將 router 實例掛載到 Vue 實例中得以啟用路由功能

由於 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);
},

console

為 Navbar 設定路由

了解 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. 方法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. 方法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 項目是否都能成功跳轉了呢~

參考資料


上一篇
Day 10:v-for 註定綁個 key
下一篇
Day 12:Router 繞去哪-active-class & exact-active-class
系列文
Vue.js 什麼意思30

尚未有邦友留言

立即登入留言