iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 6
0
Modern Web

Daily UI : 開發者版系列 第 6

Vuetify:Cinema Application › More discussion

Things We need to discuss


  • How to do Functional Component Composition Thinking ?
  • Customize CSS when using with Vuetify-like Framework ?
  • Is't possible to dev without writing any CSS ?

以上主題緊緊相連,請依序閱讀

 
 

How to do Functional Component Composition Thinking ?


先想一個問題:當你看到這張圖的時候、又或是設計師丟一張 UI 圖給你的時候( 或是你自己造一張 UI 的時候,whatever ),請問在未開發前,有誰會跟你講該圖面上的 "技術細節" 呢 ? 用前端的語言講就是:「 這個是 div 那個是 button,這個好像用 p 包起來比較合理 . . . 」,這種以技術角度去看待如何組裝出目標圖面就是 Functional Component Composition Thinking( 簡稱 FCCT,下同 )的核心基礎

首先要澄清 Component 這個名詞的使用,因為 FCCT 是個概念性、廣義性的描述語句,裡面所謂的 Component 可不是 "只有",或 "只是" 針對你打開 Vuetify 官網中的、那所謂的 UI Components,現在,請你把它想得更廣義一點:此處所謂的 Component,別再翻成組件了,因為現在這個詞彙的使用,不是直接對應到前端開發的專有名詞!

現在,你得改以 Component 的角度作思考整張 UI 圖,或許你覺得這沒什麼,但此處關鍵在於,要盡可能把圖面中所有細節改用 Vuetify 的語言做思考,什麼意思呢?例如購物車那個方塊要怎麼實作?一般人可能就想:「 div 啊,然後自己客製化 CSS,加黑色背景,連我媽也會 」要是真的只是這樣,那你可以把這個分頁關閉了

所謂 "以 Component 的角度作思考" 沒一定的答案,所以此處僅提供我的思考方式:我會把它當成一個按鈕 v-btn,所以就不再是所謂的 div( 當然我們現在不考慮實際上它到底應該是什麼比較合理,因為這僅是個示例圖,不是個真正的軟體,沒有人具體定義該元件的實際功能,你亂做沒人追殺你 )

會考慮是 v-btn,也是因發現此元件呈懸浮狀,壓在別的元件上方( 購物車按鈕至少下方壓了兩個元件 ) ,而 v-btn 除本身具有 absolutecolor 屬性,還可搭配 v-icon 使用,陰影也可靠 elevation 做調整。就連本身在空間的位置也是靠 Vuetify 既有的全域屬性 mx-auto 設定,所以就可實作成:

<v-btn
    absolute width='100' height='100' color='black' dark elevation='24'
    class='mx-auto' style='left: -70px; right: 0; top: 40%'
>
    <v-icon v-text='"shopping_cart"'></v-icon>
</v-btn>

點開 Cards 說明文件可發現,其相關屬性計有 v-card, v-card-actions, v-card-text, v-card-title。你得先搞懂它們,最終目的是一看 UI 圖面後,就能知道這圖面上有沒有東西是個 Cards,而且若有的話,就要開始思考:這卡片中的這一部分應該要放在 v-card-text,那部分實際上可跟使用者互動,所以應以 v-card-actions 予以包裹?

實際使用上,v-card 須放在最外層,這四個 API 實際都會有預設的 Styling( 例如會有預設的 padding ),這也是必須要能掌握的細節,用久其實就習慣了,但最重要必須要請讀者記住的是,因 Vuetify 元件大量採用 Flexbox 為基礎做建構,所以很多時候在使用它的元件時,須要自己心裡預設:等等這兩個 block elements 放到該元件內,會呈現橫向並排的模樣,而非縱向排列( 因為 flexbox 預設就是橫向排列 )

<v-card-title 
    class='my-2 headline justify-center' v-text='TEXT_TITLE'>
</v-card-title>

可能看 Code 就懂了:圖面上的 "The Martian" 這段文字,我們直接把它看成是 v-card-title( 當然這並非意味著 v-card-title 中只能放文字,或是只能放一個東西 ),我們之所以能把該文字於 v-card-title 內置中,靠的是 justify-center*,這個 class 一加到 v-card-title 上,就能改變其 flexbox 的預設 ( 從下圖你可發現 v-card-title 被渲染後的標籤模樣,也可看到它預設的 styling )

<v-card-text 
    class='grey--text text-center caption px-6' v-text='TEXT_DESCRIPTION'>
</v-card-text>

你可能會想:「 那為何在 v-card-text 要使文字置中,為何改用 text-center( i.e. text-align: center )**? 繼續用 justify-center 不就好了? 」。是啊!那你打開 dev tool 查看該標籤所渲染出的預設屬性之後,你會發現 v-card-text 預設並無採用 flexbox。上面我說要盡可能把圖面上的細節全都用 Vuetify 的語言做描述,以本例來說,就是包含這個段落的文字字型、顏色、大小、位置、排列、與其它元件的相對關係,都要以 Vueitfy 既有 API 予以實作,而不是自己客製化 CSS

FCCT 還沒講完,請繼續閱讀

* 更多這類 Flexbox API 相關使用方式,見

**文字相關 API( 排列、斷行與否 . . . ),見

 
 

Customize CSS when using with Vuetify-like Framework ?


若已閱畢上述資訊,這時你可能會有些想法,諸如:

  • 靠這太複雜了吧?這些 CSS 我自己寫就好了,幹嘛還要透過 Vuetify 自己定義的那些 API ?
  • 要客製化 Vuetify 的 UI 組件就直接自己寫 CSS 不也行嗎?
  • FCCT ? 不搞這個還不是照樣能用 Vuetify 嗎?
  • XXX!你這根本標題殺人
  • ...

想法沒錯,本來就沒一定要怎樣,若可以以木造房,何須鋼筋水泥?若開發的只是中小型專案,或是就算是大型專案,但 UI 並不複雜,你可這樣做,但真遇到複雜的( 因 Vuetify 是實踐 Material Design,所以此處專指那些同樣實踐此 Design Spec 的複雜 UI ),可能做到一半就掛了,除了因你客製化過多的 CSS*,有機會造成相容性問題,或甚至與原生 Vuetify 元件相沖所需多寫的 hack 以外,你並沒意識到 FCCT 所帶來的好處

使用 FCCT,等於有機會最小化你寫 CSS 或自己開發一個 UI 組件相關功能的可能性,你可能想:「 洗勒公殺小? 」;且聽老衲娓娓道來:打開上方 Codepen,好好仔細看一看,除了在按鈕上使用 inline styling,以及在 id='app' 上給個背景色,從頭到尾是否還有其它客製化 CSS ( 即不靠 Vuetify,自己所寫的 CSS )?或許這個範例簡單,你還看不出太大的好處,等到圖面複雜到一定程度時,若能正用 FCCT,一切不言自明

剛好我們這邊有延遲載入圖片,並且在圖片載入前呈現 placeholder image 和 loading indicator,請問從頭到尾你有看到我寫任何的 JS 嗎?或許你自己來做,好一點的就是用原生 <img>Vuetifyv-progress-circular, 要真這樣搞,你就非得加額外的 CSS 和 JS 才可達到目的( 當然本範例過簡單,碰到難的,痛過之後可能才會心有戚戚焉 )**

*若你很自豪你的 CSS 模組化功力,超會解 CSS 相容性問題、再難的 CSS 都能維護得當 . . . 那建議你可以把這個分頁關掉了

** 注意這邊絕對不是這個意思:會用 Vuetify + FCCT = 不用多寫其它 CSS 和 JS,然後 Web App 就做出來了( 這是 . . . 佛系 Vuetify 開發者? )

覺得 FCCT 不重要❓或是你可能覺得以上是胡言亂語,那我給個讓人心服口服的例子:請嘗試以 Vuetify 實作出這個 UI,並且不可寫任何客製化的 CSS(或是頂多寫 3 行以內的 CSS)
 

Is't possible to dev without writing any CSS ?


FCCT 的精神雖相當簡單:盡可能把 UI 上的所有細節都以 Vuetify 實作,但這可是涉及 Vuetify 元件之間如何協作、組裝,並且得具有 " 把 UI 上元件辨識成 Vuetify 的元件 " 之視角能力,你得掌握 Vuetify 到一定程度。還有,若我沒提,你可能還沒發現一件事,要真能做到 FCCT,因為你不太需要客製化 CSS 了,那是不是瀏覽器相容性問題解了至少一大半?

這可不是開玩笑的,有誰解瀏覽器相容性問題解的很開心的呢?你客製化所寫出的 CSS 沒有相容性問題嗎? 採用 FCCT 也等於是把瀏覽器相容性問題降到最低,全部透過 Vuetify API 去實作出你要的 UI,若做到這種地步,還出現相容性問題時,那就是你去官方 Github 提 Issue 的時候( 好在他們改版速度也快 ),人家畢竟專門開發這類元件的,你可能只是因為專案需要,下個專案就碰不到了,比相容性處理真的比得贏專家嗎?

講到這裡,也帶出我之前一直在思考的問題,懂 CSS 的都知道,CSS 還真不好寫、不易維護,所以就出現了 OOCSS, SMACSS, BEM . . . 近年來還出現了 Functional CSS,一堆方法論,這些都是有用、值得尊敬與學習的技術,對於筆者而言,除使用這類理論外,我反而在想的是完全相反的道路:「 如何可以不要寫 CSS ? 」,至少是否能達標 80 - 90 % ( i.e. 只要寫 10 - 20% )?

經過一段時間的實踐,我得出的結論是:「 確實可行! 」,BUT!有限制條件,情境就是,首先你得掌握一套像 Vueitfy 這類可以做到 FCCT 的 UI 框架,同時你欲實作出的 UI 所參照的 Design Spec 與該 UI 框架相同( 至少要很相近 ),當然,你懂運用 FCCT,滿足這些條件,這就是最佳使用時機,這可是會省下我相當巨大的時間去開發與維護。

若你也認同,並且想要實踐,筆者最後給的建議就是:別走極端;也就是別把 「 如何可以不要寫 CSS ? 」此想法想盡辦法套到各個專案上,這只會給你帶來麻煩,寫了多年程式後我的一個經驗就是,沒有一招打天下的,工具沒有最好的,只有最適合的,Vuex 很棒,Vue 的 Reactivity 很好用,也不代表任何情況都可以使用。


上一篇
Vuetify:Cinema Application › Implementation
下一篇
Vuetify:Fashion Header
系列文
Daily UI : 開發者版30

尚未有邦友留言

立即登入留言