4-4 使用 emotion 完成「臺灣好天氣」 UI
本單元對應的專案分支為:create-ui
。
#
單元核心這個單元的主要目標包含:
- 使用 emotion 完成「臺灣好天氣」的完整 UI
#
切版拆解在了解 emotion 的基本使用後,現在就可以實際使用 emotion 來完成臺灣好天氣的 UI !
這個單元最後會完成的畫面如下:
note
「臺灣好天氣」的設計畫面主要是參考 imgur 上的圖片 (https://imgur.com/ZLgiOyj),另外則會使用 IconFinder 上 The Weather is Nice Today 所提供的天氣圖示來完成(https://www.iconfinder.com/iconsets/the-weather-is-nice-today)。
這裡我們將根據下圖拆分成不同的 HTML 區塊:
#
Location 元件以 Location 這個區塊為例,我們預期它會是個 div
元素,因此要建立帶有樣式的元件,只需要:
定義好之後,它就是一個 React 元件,可以直接把 <Location />
放入 JSX 中:
而它最後在 HTML 中呈現出來就會是帶有一個特殊 class name 的 <div>
,這個 class name(即下圖中的 css-a7vwns
)則會對應到剛剛針對 <Location>
所撰寫的 CSS 樣式:
#
完成其他區塊的 Styled Components接下來可以繼續根據本篇最上方的架構,完成其他的 styled components,因為 CSS 的內容並不是本書的重點,為了減少不必要的篇幅,大家可以直接到下方的連結將 styled components 的部分複製到 ./src/App.js
中即可:
建立好帶有樣式的元件後,就可以根據上一個段落中架構好的區塊,依序把這些元件放入 App 元件的 JSX 中:
此時應該可以看到如下的畫面:
到目前還未載入任何和天氣有關的圖示。
#
在 React 中載入 SVG 圖示的方法在前面的單元中,我們已經把天氣圖示放到 ./src/images
的資料夾中,由於這裡我們是使用 create-react-app 這個工具建立的 React 開發環境,多數的設定 create-react-app 都已經幫開發者設定好,所以要把 SVG 載入 React 中的方式很簡單,只需要使用 create-react-app 提供的 ReactComponent
這個元件即可。
實際來看應用的方式,這裡先以白天多雲的圖示(day-cloudy.svg
)為例:
- STEP 1-1:透過
import {...} from ...
將./images/day-cloudy.svg
匯入 - STEP 1-2:在
{}
中使用 create-react-app 提供的元件ReactComponent
,透過as
可以將這個元件名稱進行修改,這裡改成DayCloudy
- STEP 2:最後就可以把載入的 SVG 圖示當成 React 元件(
<DayCloudy />
)在 JSX 中使用
提醒
上述這種載入 SVG 圖檔的方式需要使用 create-react-app 來建立專案才可以使用,否則需要自行在 WebPack 中建立對應的設定才行。另外,SVG 圖檔除了可以透過這裡所說的方式,做為 React 元件載入使用外,也可以直接匯入 SVG 當成圖片使用,這個部分的說明可以參考本單元放置於 Github 上的專案說明頁(分支 create-ui
)。
#
將 SVG 圖示套用到「臺灣好天氣」現在就可以透過這種方式實際將天氣圖示放入 App 元件中。
#
天氣圖示說明在 ./src/images
中已經放了許多天氣圖示,這些圖示共可會分成三類,第一類的圖示會在白天使用,檔名以 day
開頭,會以太陽作為基底;第二類的圖示則在晚上使用,檔名以 night
開頭,會以月亮作為基底;其他的圖示則沒有特別區分白天和晚上。
#
將需要使用的圖示載入現在就讓我們來把相關的圖片載入進來,這些圖示分別是「白天多雲」、「風速」、「降雨」、「重新整理」:
接下來就可以把這些圖示直接當成 Component 來使用,放入 JSX 中:
現在的畫面會像這樣子:
圖片帶進來後,因為沒有設定寬高,看起來會破版的有點嚴重。
#
調整 SVG 圖示的樣式#
直接使用 CSS 選擇器來調整樣式對於這些 SVG 的元件來說,最後轉譯到網頁的時候其實就是把 SVG 的程式碼放入 HTML 內,因此一樣可以透過 CSS 選擇器去選到對應的 SVG 後進行樣式的調整。這裡我們先調整一下 <AirFlow />
和 <Rain />
的部分。只須在當初定義 styled components 的地方去添加 CSS 修改 SVG 的樣式即可。
以 AirFlow 的元件來說,可以在裡面選到 svg
元素後進行樣式調整:
同樣的,以 Rain 元件來說:
重新整理的 Refresh 元件一樣可以透過這樣的方式加以調整:
現在可以看到在風速、雨量和重新整理的部分大小都已經調整好了:
看起來已經大致上完成了,最後還希望能調整一下天氣圖示(白天多雲)的部分,因為不同的天氣圖示可能寬高會不一樣,這裡希望能夠限制一下天氣圖示的寬度,以因應不同的氣候狀況。
#
根據某一元件進行樣式調整上面我們使用 Emotion 來「建立」帶有樣式的 styled components,並在裡面透過 CSS 選擇器選到 svg 標籤後進行調整。但 Emotion 不僅可以用來建立帶有樣式的元件,還可以將「原本就存在」的元件添加樣式。
什麼意思呢?
舉例來說,剛剛我們透過 import
載入的 SVG 是一個 React 元件,例如,<DayCloudyIcon />
,現在如果我們想要為這個原本就存在的元件添加樣式時,可以使用 const 新元件 = styled(<原有元件>)
這樣的寫法:
也就是說,除了原本是在 styled.<html-tag>
後面加上一個 HTML 標籤,現在則是放入一個 React 元件,然後就可以在裡面撰寫 CSS 樣式,並修改該元件的樣式。
以實際的樣式來說,這裡 DayCloudy
這個元件是根據 DayCloudyIcon
這個元件而來,並且可以對它添加 CSS 樣式:
最後在 JSX 的地方,就要把原本使用 DayCloudyIcon
改成用新的帶有樣式的元件 DayCloudy
:
現在透過 npm start
後完成的畫面會像這樣:
#
換你了!完成「臺灣好天氣」 UI現在換你來完成「臺灣好天氣」的 UI,可以參考下面的順序:
- 了解「臺灣好天氣」切版時的區塊結構
- 使用 emotion 建立帶有樣式的 styled components(可於網址下載撰寫好的樣式)
- 載入 SVG 圖示到 React 元件中(包含
day-cloudy.svg
,airFlow.svg
,rain.svg
和refresh.svg
) - 使用 CSS 選擇器的方式修改 SVG 圖示的樣式
- 使用 emotion 修改原有 SVG 元件的樣式
提醒讀者們,關於本單元的程式碼都可以在專案的 create-ui
分支中檢視完整的程式碼,並可以點擊「時鐘」圖示即可檢視本單元程式碼有變更的部分。另外,若有補充的資訊同樣會放在該分支的專案說明頁的。
本單元使用到的連結、完整程式碼與變更部分(時鐘圖示)可於 create-ui
分支檢視:https://github.com/pjchender/learn-react-from-hook-realtime-weather-app/tree/create-ui