iT邦幫忙

2025 iThome 鐵人賽

DAY 2
0
Vue.js

打造銷售系統30天修練 - 全集中・Vue之呼吸系列 第 2

Day 2:[Vueの呼吸・壹之型] 架構設計 - 從Prototype到Component架構

  • 分享至 

  • xImage
  •  

專案現況: AI 給我們的 Prototype

在昨天的探索中,我們得知我們的需求「銷售系統」是基於 HTML、CSS 和 JavaScript 的靜態原型(prototype)。每個頁面都是一個獨立的 HTML 檔案,例如 index.html (登入頁)、dashboard.html (主畫面)、order-management.html (訂單管理) 等。

這邊起初只是為了可以快速 Demo 並確認需求的 prototype 所以透過 AI 產出了一份原始碼,讓我們能夠快速地看到一個可操作的介面,並與團隊進行溝通。

實際上, 原型 (Prototype) 和 產品 (Production) 之間存在著一段非常大的距離。

這份由 AI 產出的程式碼,雖然能動,但若要將其作為一個可長期維護的「產品」,它的架構存在著一些問題,因此,我們將以 Vue 為核心進行重構,目標是建立一個可維護、可擴展的全新基礎。


讓我們來看看以下這幾個頁面的程式碼

幾乎每個頁面都有一個結構相似的 header,用來顯示當前頁面的標題,但它們是在每個檔案中寫死的。

dashboard.html 的標題:

   <header>
       <h1>銷售系統儀表板</h1>
   </header>

order-management.html 的標題:

   <header>
       <h1>訂單管理</h1>
       <a href="dashboard.html" class="back-button">返回主頁</a>
   </header>

customer-management.html 的標題:

   <header>
       <h1>客戶管理</h1>
       <a href="dashboard.html" class="back-button">返回主頁</a>
   </header>

inventory-query.html 的標題:

   <header>
       <h1>庫存查詢</h1>
       <a href="dashboard.html" class="back-button">返回主頁</a>
   </header>

這樣子會有幾個問題:

  • 結構不一致:像 dashboard.html 的 header 就沒有「返回主頁」按鈕,這種差異導致每個 header 都得客製化。
  • 修改麻煩:如果今天我們想在所有 header 的標題旁邊都加上一個icon,我們就必須去修改每一個 HTML 檔案。

讓我們接著再看看 dashboard.htmlorder-management.html 的一小部分程式碼片段:

dashboard.html 的按鈕:

<a href="order-management.html" class="dashboard-button">
    <i class="fas fa-file-alt"></i>
    <span>訂單管理</span>
</a>

order-management.html 的返回按鈕:

<a href="dashboard.html" class="back-button">返回主頁</a>

從這邊可以發現,即使是功能單純的「按鈕」,在不同頁面中也有著不同的寫法和樣式。隨著系統功能越來越複雜,這種寫法將會導致以下問題:

  • 重複的程式碼:相似的 UI 元素 (如頁首、按鈕、卡片) 會在不同頁面中不斷重複,難以統一管理。
  • 維護困難:當需要修改一個共用元素時 (例如,更新所有按鈕的樣式),我們必須到每個頁面中手動修改,費時又容易出錯。
  • 缺乏擴展性:每個頁面都是一個巨大的整體,難以將功能拆分或複用。

Vue 的元件化架構

為了解決以上問題,我們可以使用 Vue 的核心思想:元件化 (Component-based Architecture)

在 Vue 中,我們可以將一個複雜的頁面,拆分成一個個獨立、可重複使用的 元件 (Component)。每個元件都包含自己的 HTML 模板、CSS 樣式和 JavaScript 邏輯。

https://ithelp.ithome.com.tw/upload/images/20250902/20177694pvfSBCponb.png

這種架構的優點顯而易見:

  • 高複用性:像 < Article >、< Item > 這類可重複出現的元件,可以在不同區塊或頁面中直接使用。
  • 易於維護:修改單一元件(例如 < Header >),即可同步影響所有引用的地方,降低重工。
  • 關注點分離:每個元件專注於自己的職責,例如 < Main > 負責主要內容、< Aside > 處理側邊資訊,程式碼更乾淨易懂。

拆解我們的銷售系統

現在,讓我們來實際規劃如何將現有的 POS 系統拆分成 Vue Component。

1. 找出可以複用的 UI 元件

我們可以從現有的 HTML 中找出以下可複用的 UI Component:

  • BaseButton.vue:所有可點擊的按鈕,例如「登入」、「返回主頁」、「查看詳情」等。我們可以透過 props 來控制它的文字、樣式和行為。
  • PageHeader.vue:每個頁面的標題列。我們可以透過 prop 傳入標題文字。
  • BaseCard.vue:在Dashboard中,每個功能的 entry point 都是一張卡片。這個元件包含圖示、標題和連結。
  • OrderSearchForm.vue:處理所有跟「搜尋」相關的邏輯,例如:管理輸入框的狀態、處理搜尋按鈕的點擊事件、驗證輸入內容等。
  • BaseInput.vue / Select.vue:表單中的輸入框和下拉選單,可以封裝成獨立的元件以方便管理表單狀態。
  • BaseTable.vue:訂單管理頁面中的表格。我們可以將表頭和資料作為 props 傳入,讓它動態生成表格。

2. 設計元件樹 (Component Tree)

在 Vue 中,應用程式是由一個個元件組成的樹狀結構。我們的 POS 系統可以被設計成如下的結構:

  • App.vue:根元件,作為整個應用程式的容器。它將包含路由視圖 (<router-view>),用來顯示不同頁面的內容。

  • 頁面元件 (Page Components):每個 HTML 檔案都將轉化為一個頁面元件。

    • Login.vue
    • Dashboard.vue
    • OrderManagement.vue
    • ...等等
  • 基礎 UI 元件 (UI Components):我們剛剛找出的可複用元件。

讓我們以「 index.html(登入頁)」為例,看看它的元件樹會長什麼樣子:

  Login.vue (登入頁面本身)
    └── div.login-card (主要的卡片容器)
    │
    ├── div.login-header (包含 Logo 和標題)
    │
    ├── BaseSelect.vue (用於選擇門市)
    │
    ├── BaseButton.vue (用於 Google 登入)
    │
    ├── BaseButton.vue (用於 LINE 登入)
    │
    └── div.login-footer (底部的說明文字)

看到這裡,你可能會問一個問題:『為什麼 div.login-card 和 div.login-header ... 還是 div,沒有被建立成元件呢?』

這是一個非常好的問題,我們可以透過幾個簡單的原則來判斷:

  1. 重複性 ( Is it Reusable? ) : 是否會在專案的多個地方被使用?

    • 我們的 BaseButton.vue 會,所以它必須是元件。
    • 但 div.login-card 這個版型只會用在登入頁這一次,所以它不需要。
  2. 複雜性 ( Is it Complex? ) : 是否包含自己獨立的、複雜的資料或使用者互動邏輯?

    • 像是一個包含多個篩選條件的「搜尋表單」是複雜的,應該被封裝。
    • 但 div.login-header 只是一個靜態的標題容器,它不具備任何邏輯。
  3. 可測試性 ( Is it Testable? ) : 是否需要獨立測試?

    • 登入邏輯需要測試,所以應該要有BaseButton.vue元件
    • 純粹的樣式容器不需要測試,保持為 div 即可

元件化的目標是化繁為簡。當你發現建立一個元件所帶來的成本,超過它所需要解決的問題時,那可能就是一種 『過度設計』

透過這樣的設計,Login.vue 頁面本身變得非常簡潔,它只負責組合各個子元件,而不關注每個按鈕或表格的具體實現細節。


總結

今天,我們完成了從 Prototype 到 Component 的思維轉換,並為我們的銷售系統設計了一個清晰的 Vue 元件架構。

今日重點回顧:

  1. Component 架構:高複用性、易於維護/測試、關注點分離。
  2. 元件拆分:找出可複用的 UI 元素,並將其封裝成獨立的 Vue 元件。
  3. 元件樹:將頁面由一個個元件組合而成,形成清晰的樹狀結構。

明天,我們將繼續深入Vueの呼吸・貳之型,探討在 Vue 中如何管理我們的資料流,猪突猛進!!


上一篇
Day 1:[Vueの呼吸・前言]
下一篇
Day 3:[Vueの呼吸・貳之型] 資料流設計 - 初探銷售系統的狀態規劃
系列文
打造銷售系統30天修練 - 全集中・Vue之呼吸5
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言