https://codepen.io/hereiscasio/pen/wQvVzP?editors=1000
#1 Cards, #2 Images, #3 Grids, #4 Buttons, #5 Progress > Circular
作為開頭的範例*,這應該既簡單,但又稍帶點挑戰性( 而且 . . . 還蠻 Fashion 的?),畢竟是起頭,要講的較多,所以會拆成兩天來說明,明天講如何以 Functional Component Composition 的視角看待整個 UI,今天純粹講技術細節
有些這張圖會用到的 UI 組件( e.g. Cards ),其相關使用方式留明日再談,因本日內容已過多,會爆表。請先打開上圖下方所提供的 Codepen( 必要時請也打開 Vuetify 官方文件閱讀,我不會鉅細彌遺的把每個使用到的 API 都講到( 每天要是都這樣講就有點是在發廢文 ),但大致都會帶到,然後你也得習慣、懂得如何查閱官方文件 ),以下提供的都是簡化後的程式碼:
<div id="app"><v-app>
<v-row justify='center' align='center'>
<v-card height="540" width="320" elevation='24'>
<v-img ...>
<v-btn ...>
<v-btn ...>
<v-card-title ...>
<v-card-text ...>
</v-card>
</v-row>
</v-app></div>
先來看最外層,v-app
這個標籤一定得使用在所有 Vuetify 元件最外層;這張 UI 圖之所以能夠置中,就是靠 Flexbox 達成,也就是 v-row
( 使用 v-row
不見得非得配合 v-col
),若你對 Flexbox 的 API 熟悉,你應很快能了解到其實 v-row
就像是你先給個 div,並且在其上宣告 display: flex
罷了
<v-img :src="URL_IMG" :lazy-src='URL_PLACEHOLDER'>
<template v-slot:placeholder>
<v-row
class="fill-height ma-0" align="center" justify="center"
>
<v-progress-circular
indeterminate color="grey lighten-5">
</v-progress-circular>
</v-row>
</template>
</v-img>
這其實就是那個太空人圖片,你可能會想說幹嘛不用原生的 <img>
, 其實也可以,但你就會需要做很多事情,若你仔細觀察,重新整理頁面時,會發現在圖片還沒載入前,會先載入一個 placeholder 圖片( :lazy-src='URL_PLACEHOLDER'
),並且在圖片上搭配旋轉的 loading indicator( v-progress-circular
)。這東西真要自己搞 . . . 開玩笑 . . . 我知道有些開發者很喜歡自幹,剛好我是特別懶惰的XD
再來還有些細節要講,ma-0
是 margin all 0 的縮寫( 所以舉一反三,pr-2
就是 margin right 2,pb-n10
為 padding bottom negative 10,這可自己看,沒難度可言,詳見此 ),而 fill-height
是指把 v-row 的高度稱高到與它的 parent( 此處為 v-img
) 一樣高,若沒先這樣做,靠 v-row
也無法讓 loading indicator 於該圖片上呈垂直水平置中
<v-btn
absolute width='100' height='100' color='white' elevation='24'
class='mx-auto subtitle-1' style='left: 0; right: -70px; top: 44%'
v-text='NUMBER_RATING'
>
</v-btn>
<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>
這兩個按鈕,就是圖片中間看起來很牛逼的漂浮物,你會發現以上用了 inline styling( i.e. style=
)原因是面對這種把 A 懸浮在 B 的排版上,暫時想不到有更好的解法**,但事實上這影響不大,尤其是你有機會開發相當龐大、複雜 UI 的時候。至於 v-icon
的值( i.e. "shopping_cart"
)取自 Google 提供的 Icons 。
v-card
在渲染後所產出的標籤會帶有 position: relative
,而 v-btn
位於其內,這就是為何會用到 absolute
屬性的原因,所以此處暗示一件相當重要的事,別以為這類 UI 框架幫你做了很多事,就不需看它實際的一些技術細節,這恰恰是錯誤心態,當年 Sass 正流行時,許多相關框架如雨後春筍一個個誕生;有個相當知名,並且台灣也有不少人在學的就是 Susy,它也幫我們做了很多雜事,但同樣你得了解具體「 它是如何做到的 」,否則實務上碰到困難,你可能就無從解起
mx-auto
為 margin: 0 auto
縮寫,subtitle-1
則是已事先定義好的文字 styling( 更多請見此 ) ,文字顏色預設是黑色,但我們設定按鈕背景為黑( color='black'
),所以得靠 dark
快速幫我們把特定的 UI 組件 "反轉色調",這樣文字就會變成白色,此屬性不但能用在許多 UI 組件上,甚至可用在整個 app 最上層,一次反轉整個 App UI 的色調,可謂相當強大的功能
**雖然可靠諸如 ml-n12
的 類似API 達到負值的 margin,但受限於其值最大只到 12
* 設計圖來源見此