iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 28
1
Modern Web

Angular 深入淺出三十天系列 第 28

[Angular 深入淺出三十天] Day 27 - Angular 小學堂(四之一)

這次小學堂要跟大家一起練習的是一個簡單的 EC 網站。

素材是來自剛好在鐵人賽前夕時,由六角學院The F2E - 前端修練精神時光屋 舉辦的 【網頁排版PK戰】甜點電商 活動,在此特別感謝六角學院!!

在這次的練習過程中,你可以根據設計稿自己動手從 HTML 與 CSS 開始篆刻;也可以使用我自己參加活動時切好的版型直接套版。

至於效果與樣式除了可以直接看設計稿的原始設定之外,也可以直接參考我已經放到 GitHub Pages 上的靜態頁面的設定。

在開始前,我們先看一下設計稿或是先逛一下已經刻好的靜態頁面,了解一下這個甜點電商總共有哪些頁面、哪些功能;有哪些資料我們需要事先準備、路由該如何規畫等等,這樣後面在實作的時候才會事半功倍。

準備好了嗎?開始囉!!


UI 元件規劃

從頁面來看的話,大致上應該會有這幾個頁面:

Imgur

不過如果是從 UI 元件的角度來看的話,應該會是這樣:

Imgur

我大概分享一下為什麼我會這樣切分的原因:

Imgur

  • Layout 的部份其實可有可無,因為用 AppComponent 當共用層也是可以,只是我不想要讓共用層跟 AppComponent 黏在一起才這樣切開。而且我覺得這樣會比較有彈性一點,雖然這個專案應該是不需要,畢竟只是練習,不會有什麼擴充的可能,所以後續實作我們就直接放 AppComponent 裡就好。

Imgur

Imgur

  • Home 裡面有一些甜點品項,這部份會跟 ProductList 共用,所以我把共用的 UI 元件另外拉到 Shared 裡面,讓 ProductList 跟 Home 之後可以共用。

Imgur

  • 甜點這頁我是這樣切分的:紅色框框是共用的區塊-ProductSection;亮紫色框框是商品清單-ProductList;亮藍色框框則是會跟首頁共用的-ProductItem 。

  • Login、Cart 與 Success 沒什麼好說的,很單純地自己一個頁面。

Imgur

  • 結帳的整個流程其實都只有換同一塊地方,所以一樣切成共用的 CheckoutFlow 以及各自的 CustomerInfo、PaymentInfo 跟 ReceiptInfo。

路由規劃

路由的部分,我的想法是這樣:

Imgur

  • 預設頁面是首頁,所以是空字串。
  • 甜點共用層是 products ,子類別則用 :type 的方式來切換顯示的甜點類別,屆時預設顯示所有類別。
  • 登入 login 、購物車 cart 、結帳成功 success 沒什麼好說。
  • 結帳共用層是 checkout ,其他流程如運送則是 customer-info 、付款是 payment-info 、發票是 receipt-info

資料準備

Angular 是靠資料來驅動,所有很多重複的東西我們都可以透過使用資料的方式來做處理,讓我們可以不用寫那麼多程式碼。

以這個練習來說,我大概會先準備以下資料:

  • 導覽列的選單資料。像是:
const menus = [
  {
    title: '首頁',
    path: ''
  },
  {
    title: '甜點',
    path: 'products'
  },
  {
    title: '登入',
    path: 'login'
  }
];
  • 商品資料。像是:
const products = [
  {
    type: 'today',
    name: '焦糖馬卡龍',
    price: 450
  },
  {
    type: 'popular',
    name: '巧克力熔岩',
    price: 400
  },
  {
    type: 'new',
    name: '提拉米蘇',
    price: 350
  }
];
  • 甜點類別選項的資料。像是:
const productTypes = [
  {
    title: '所有甜點',
    type: ''
  },
  {
    title: '本日精選',
    type: 'today'
  },
  {
    title: '人氣推薦',
    type: 'popular'
  },
  {
    title: '新品上市',
    type: 'new'
  }
];
  • 路由的資料。像是:
const path = {

  // 首頁
  home: '',
  
  // 甜點
  products: 'products',
  
  // 登入
  login: 'login'

};

這些資料之後在開發的時候都會用得到,且會增進開發的效率並使你的程式碼更容易被維護。

當資料都準備就緒之後,我們就可以開始建立新專案並把我們事先準備好的東西加進去了。

其實也不一定要先準備好這些資料,要用到的時候再建也可以。

啟程

首先當然是要先建立專案囉:

ng new Angular30DaysECApplication --skip-tests --routing

建立完專案之後記得用 VSCode 開啟這個專案,後續都將用 VSCode 的終端機來下指令。

接著我們可以先用 CLI 把我們剛剛規劃好的部分都先產生出來。

  • Home 的部份:
ng generate module home --routing
ng generate component home
  • ProductSection 的部份:
ng generate module product-section --routing
ng generate component product-section
  • ProductList 的部份:
ng generate component product-section/product-list
  • Login 的部份:
ng generate module login --routing
ng generate component login
  • Cart 的部份:
ng generate module cart --routing
ng generate component cart
  • Success 的部份:
ng generate module success --routing
ng generate component success
  • Checkout 的部份:
ng generate module checkout --routing
ng generate component checkout
  • CustomerInfo 的部份:
ng generate component checkout/customer-info
  • PaymentInfo 的部份:
ng generate component checkout/payment-info
  • ReceiptInfo 的部份:
ng generate component checkout/receipt-info
  • 共用的 ProductItem 的部份:
ng generate module shared/product-item
ng generate component shared/product-item

雖然大部分的 UI 元件在建立的時候因為跟模組同名的關係, Angular CLI 就會幫我們在其模組的 declarations 加入該 UI 元件,但還是有少部分跟模組不同名的 UI 元件需要我們手動處理。

像是 ProductListComponent 的部份:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { ProductSectionRoutingModule } from './product-section-routing.module';
import { ProductSectionComponent } from './product-section.component';
import { ProductListComponent } from './product-list/product-list.component';

@NgModule({
  imports: [
    CommonModule,
    ProductSectionRoutingModule
  ],
  declarations: [ProductSectionComponent, ProductListComponent]
})
export class ProductSectionModule { }

以及結帳流程會用到的 CustomerInfoComponent、PaymentInfoComponent、ReceiptInfoComponent:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { CheckoutRoutingModule } from './checkout-routing.module';
import { CheckoutComponent } from './checkout.component';
import { CustomerInfoComponent } from './customer-info/customer-info.component';
import { PaymentInfoComponent } from './payment-info/payment-info.component';
import { ReceiptInfoComponent } from './receipt-info/receipt-info.component';

@NgModule({
  imports: [
    CommonModule,
    CheckoutRoutingModule
  ],
  declarations: [
    CheckoutComponent,
    CustomerInfoComponent,
    PaymentInfoComponent,
    ReceiptInfoComponent
  ]
})
export class CheckoutModule { }

除此之外,我們有個共用的 UI 元件 - ProductItemComponent,之後會給 HomeModule 以及 ProductSectionModule 共用,所以記得要在 ProductItemModule 裡把 ProductItemComponent 匯出,別的模組才能使用:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ProductItemComponent } from './product-item.component';

@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [ProductItemComponent],
  exports: [ProductItemComponent]
})
export class ProductItemModule { }

這邊處理好之後我們休息一下!

明天我們從路由的設定開始處理。


上一篇
[Angular 深入淺出三十天] Day 26 - 路由總結(二)
下一篇
[Angular 深入淺出三十天] Day 28 - Angular 小學堂(四之二)
系列文
Angular 深入淺出三十天33

尚未有邦友留言

立即登入留言