iT邦幫忙

2025 iThome 鐵人賽

DAY 10
0

在 Projects 區塊中,每個專案都會以卡片形式展示。隨著專案數量逐漸增加,若全部一口氣呈現,區塊會過於冗長,影響閱讀體驗。為了避免這種狀況,設計上加入了展開/收合按鈕,用來控制顯示的卡片數量,讓頁面維持簡潔,保留使用者探索的彈性。
https://ithelp.ithome.com.tw/upload/images/20250923/20178581dCrtqCdRd8.png

預期的操作效果是:初始僅顯示 2-3 個卡片&View More 按鈕,點擊後展開所有卡片 & View Less 按鈕,再次點擊按鈕後,縮回顯示 2-3個卡片。

  • 展開狀態:按鈕文字 View Less,顯示所有卡片
  • 收合狀態:按鈕文字 View More,顯示2個卡片
// projects/projects.vue

<template>
    <div class="px-md-12 px-lg-16 px-7 py-16 bg-light-yellow">
        <div class="text-brown text-h3-semi-bold mb-3 text-center">
            Projects
        </div>
        <div class="mt-5 text-brown"
            :class="isDesktop ? 'text-h5-regular custom-padding': 'text-h6-regular'">
            大學時期參與許多社團事務,包括彰師小生物、彰師大升學輔導種子計畫以及彰師大諮輔志工團。 其中「彰師小生物」是提供學生課程評價搜尋的服務,目前收錄1000則以上的評價回饋。我主要負責粉絲專頁的文案平面設計,以及網站平台前端網頁的建置與維護,目前粉專有1300的追蹤人數,平台有6500以上的使用者,也藉此累積了很多作品及經驗。
        </div>

        <div v-for="(project, index) in visibleProjects" :key="index">
            <ProjectCard :project="project"></ProjectCard>
        </div>
				
	    // toggle
        <div
          class="text-brown text-center text-decoration-underline"
          :class="isDesktop ? 'text-h4-semi-bold mt-10' : 'text-h5-semi-bold mt-6'"
          @click="toggleExpand"
        >
          {{ expand ? 'View Less' : 'View More' }}
      </div>
    </div>
</template>

<script setup>
import { ref } from 'vue';
import useInnerWidth from '~/composables/useInnerWidth';
import ProjectCard from './project-card.vue';

const { isDesktop } = useInnerWidth();

const projects = ref([
  {
    title: 'title',
    skills: ['skill1', 'skill2', 'skill3'],
    designConcept: 'url',
    productUrl: 'url',
  },
  ...
]);

const expand = ref(false);

// 展開時要顯示全部卡片,收合時僅顯示2個
const visibleProjects = computed(() =>
  expand.value ? projects.value : projects.value.slice(0, 2)
);

const toggleExpand = () => {
  expand.value = !expand.value;
}
</script>

為什麼這裡要用 computed?

  • 自動依賴追蹤的函式

    • visibleProjects 依賴 expand.valueprojects.value
    • 當這兩者任何一個改變時visibleProjects 會自動重新計算。
    • 不需要手動寫監聽(watch)或在模板裡重複寫判斷式。
  • 模板更乾淨

    • <template> 裡只需要寫 v-for="project in visibleProjects"

      而不用在模板裡加 expand ? projects : projects.slice(0, 2) 這種判斷式,維護起來更直觀。

  • 效能優化

    • computed 有快取(cache),只要依賴的值沒變,就不會重新計算。
    • 相較於用 methods,每次 render 都會重新執行,computed 更省資源。

為什麼不用 watch?

watch → 是用來「觸發副作用」,像是「資料變了就打 API、console log、寫入 localStorage」這類有外部效果的事情。

使用生命週期點時要先思考各自的優點,和有沒有更簡化的方法,今天就記錄到這!


上一篇
Day 9 Projects section 1 — ProjectCard 元件設計
下一篇
Day 11 Contact section + 基礎表單設計
系列文
《運用通勤時間打造線上履歷作品集:30 天 Nuxt 自我挑戰》11
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言