iT邦幫忙

2021 iThome 鐵人賽

DAY 26
0
Modern Web

Vue.js 什麼意思系列 第 26

Day 26:v-if 才做選擇,v-show 全都秀

目前的版面配置是基本的瀑布流效果,而此模式較著重在顯示書本封面圖片,一列只能出現三本書單,RWD 的情況下又會再壓縮顯示空間,相對在瀏覽資訊上的速度會較慢,因此延伸出了新的需求:切換檢視模式。這個算是相當常見的功能,例如 Google Drive 雲端硬碟,一鍵切換清單檢視或格狀檢視,同時顧及因應不同情境需要切換檢視需求的使用者體驗。

在處理切換模式之前,我們先做好前置作業,新增一個以表格方式呈現的資料列表。

<div class="booktable">
  <table>
    <thead>
      <tr>
        <th>ISBN</th>
        <th>書名</th>
        <th>原價</th>
        <th>特價</th>
        <th>連結</th>
        <th>圖片</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="book in bookList" :key="book.id">
        <td>{{ book.ISBN }}</td>
        <td>{{ book.name }}</td>
        <td>{{ book.originPrice }}</td>
        <td class="bargain">{{ book.sellPrice }}</td>
        <td><a :href="book.link" target="_blank">連結</a></td>
        <td><img :src="book.image" alt="book image" /></td>
      </tr>
    </tbody>
  </table>
</div>

排版樣式就因人而異進行處理了,例如可以設置表格固定高度並處理縱向 overflow 問題,同時固定表頭位置,就像 Excel 凍結首列的功能。
table

截至目前在 BookList.vue 元件內會同時存在兩種檢視模式,因此需要再新增切換按鈕,我們先簡單設置兩個 <button>,並在其上監聽 click 事件以及檢視狀態。

預設 isShelf: true,因此一開始會以圖表模式呈現,希望達到的效果是當點擊「顯示表格」的按鈕時,會因為變成 isShelf: false 而改為呈現表格模式。

<button class="image_mode" @click="isShelf = true">顯示圖表</button>
<button class="table_mode" @click="isShelf = false">顯示表格</button>
data() {
  return {
    isShelf: true,
  };
},

v-ifv-else

接下來剩下關鍵設置,在兩種檢視模式的資料最外層,加上 v-ifv-else 進行條件式渲染。其判斷方式就是當條件為 true 時,才會顯示隸屬於設定條件層級之內的所有程式碼,意即在父層設定條件之後,符合條件的子層內容才會顯示在畫面上,因此當 v-if 為 true 時,才會顯示 v-else 的子層內容。

<div class="bookshelf" v-if="isShelf">
    <!-- 略 -->
</div>

<div class="booktable" v-else>
	<!-- 略 -->
</div>
data() {
  return {
    isShelf: true,
  };
},

了解切換過程之後,可以再進一步將兩個按鈕合而為一,只需點擊同一個按鈕就能進行切換檢視模式。

v-if on <template>

一般在 .vue 單一元件檔案內,最外層的 <template> 內只能包含一個根元素,若超過一個元素會報錯。(此為 Vue 2 的限制規則,但在 Vue 3 已改為可支援同時存在多個根元素,詳見 Fragments 說明版本差異)

<template>
  <h1>BookList</h1>
  <div class="BookList">
</template>

template

<template> 其實還可以作為一個不會被渲染到畫面中的包裝元素(Conditional Groups with v-if on <template>),只負責處理邏輯判斷,並且能在一個 .vue 檔案內使用多個 <template>。

因此利用 <template> 的包裝特性,再加上條件運算子綁定樣式以區分不同檢視模式,便能整合按鈕功能。

<button
  :class="[isShelf ? 'image_mode' : '']"
  @click="isShelf = !isShelf"
>
  <template v-if="isShelf">顯示圖表</template>
  <template v-else>顯示表格</template>
</button>

image mode
table mode

v-if 條件渲染 VS v-show 條件顯示

條件式渲染還有另一個判斷方式,就是控制元素 display 屬性的 v-show,其內容無論如何都會被保留在 DOM 中,顯示與否是透過 display: none 開關而定。

  • v-ifv-else:只有表達式回傳 truthy 值的元素才會被渲染到畫面上。
    https://ithelp.ithome.com.tw/upload/images/20211011/201412715VvuHlHUDv.png

    https://ithelp.ithome.com.tw/upload/images/20211011/20141271WEq1jM8RJG.png

  • v-show:即使表達式回傳 falsy 值的元素也會被保留在 DOM 中,只是因為 display: none 才未顯示在畫面上。
    https://ithelp.ithome.com.tw/upload/images/20211011/20141271u1ZO0COhLK.png

參考資料


上一篇
Day 25:從頭開始的 Scroll Behavior
下一篇
Day 27:語系包在 i 身上-Vue I18n 前置作業
系列文
Vue.js 什麼意思30

尚未有邦友留言

立即登入留言