iT邦幫忙

2021 iThome 鐵人賽

DAY 14
2

Day14-Banner

「噁 ... 那條是什麼鬼東西啦!」
「對啊 ... 也太可怕了吧 ...」

「嘔! 還很臭欸 ...」
「那是阿嬤的裹腳布吧!!!!」

「不是啦 ...,那個就 Tailwind 的寫法咩~」
「又臭又長的 ... 我受不了我要閃人了!」

呃 ...。

摁,對啦,那一串 class 是真的 ... 很長。
但也並不是完全沒有辦法啦!

今天的內容很輕鬆,就是要來學習提取成元件的方法,
縮短那些又臭又長的 class 吧!!
 

carrotPoint 裹腳布原料

今天要用到我們之前做過的,在本地端安裝的 Tailwind 專案。

如果沒有建專案的人,也可以透過 Playground 練習。在目前的範圍內能做到的事情是一樣的。

沒有裹腳布的人,我準備在這裡:

那鼻子捏著,我們準備開始囉!
 

carrotPoint 提取

「兔兔!提取說得簡單,但要怎麼做啊!?」

別擔心~要提取,當然是要尋找它們可以共用的功能啦! 讓我們來看看有哪些功能是相同的部分:

<div class="flex justify-evenly p-10 focus-within:bg-green-100 group">
  <box class="bg-red-500 hover:bg-red-400 ring-red-300 focus:ring-4 group-hover:text-gray-600 font-bold flex justify-center items-center rounded-md cursor-pointer outline-none w-20 h-20 text-3xl text-white" tabindex="0">
    1
  </box>
  <box class="bg-blue-500 hover:bg-blue-400 ring-blue-300 focus:ring-4 group-hover:text-gray-600 font-bold flex justify-center items-center rounded-md cursor-pointer outline-none w-20 h-20 text-3xl text-white" tabindex="1">
    2
  </box>
</div>

看來看去之後,大概就是這一段:

focus:ring-4 group-hover:text-gray-600 font-bold flex justify-center items-center rounded-md cursor-pointer outline-none w-20 h-20 text-3xl text-white

我們把共用抽出來之後,加入一個新的 class,box

<div class="flex justify-evenly p-10 focus-within:bg-green-100 group">
  <box class="box bg-red-500 hover:bg-red-400 ring-red-300" tabindex="0">
    1
  </box>
  <box class="box bg-blue-500 hover:bg-blue-400 ring-blue-300" tabindex="1">
    2
  </box>
</div>

那接下來我們就要來把這個抽取出來的部分做成元件囉!
 

carrotPoint 製作元件

通常製作的元件,我們會放在主要 css 檔中,也就是貼有 @tailwind base@tailwind components@tailwind utilities 這三個指令的那個檔案。

「可是兔兔,Tailwind 的 class 要怎麼當 css 用啊?」

這個就別擔心了!
還記得我們在 day2 中提到的 @apply 指令嗎?

有了這個 @apply
我們就可以在 CSS 檔中直接使用 Tailwind 的功能性 class!

現在我們要幫 .box 這個 class 新增樣式,只要打好基本結構、寫個 @apply 然後貼上:

.box {
  @apply focus:ring-4 group-hover:text-gray-600 font-bold flex justify-center items-center rounded-md cursor-pointer outline-none w-20 h-20 text-3xl text-white;
}

既然稱為元件,他就應該要有自己的樣式!
所以我們幫他加個背景顏色 bg-gray-500

.box {
  @apply bg-gray-500 focus:ring-4 group-hover:text-gray-600 font-bold flex justify-center items-center rounded-md cursor-pointer outline-none w-20 h-20 text-3xl text-white;
}

貼完之後去瀏覽一下畫面,會發現 ...

「奇怪了兔兔!怎麼變成這副醜陋的模樣!」

沒事沒事,只是沒有再編譯一次而已啦~
我們之前在安裝及設定的時候不是有說過如果配置檔有修改或者主要 css 檔有修改,就要重新編譯一次嗎?

而且我們在 day12 中也有為了要方便使用,而弄成指令可以一鍵編譯。那我們現在就執行那行指令來編譯吧:

npm run build

編譯要等一段時間,編譯完成之後就可以看到網頁上的樣式改變了!

「欸? 兔兔啊 ...,所以我說那個顏色 (醬汁) 咧?」
「怎麼全部都變成灰色了!」

別緊張~ 這樣是正常的! 因為這是渲染層級的問題。
所以接下來就要來了解 Tailwind 的渲染層級啦~
 

carrotPoint 渲染層級

渲染層級的問題我們在 day2 的函數與指令段落中有討論過,可以回去複習哦!

不過不回去複習也沒有關係,我們這邊會再重新提到一次。

基本上,Tailwind 分為 basecomponentsutilities 三個層級,而這三個層級是依序渲染的,也就是說樣式的權重由高到低是:

utilitiesbg-red-500sm: ... 等常用功能

components:提取的元件

base:Preflight 等等的基底樣式

這樣應該很明瞭要放在哪個層級了吧!
沒錯,就是 components

不過知道歸知道,但到底該怎麼做呢?
這就是要用到我們在 day2 中有提過的指令:@layer

@layer 指令能夠宣告層級,然後讓我們把樣式寫在層級之中,在 Tailwind 編譯時會自動對應層級將樣式搬到正確的位置,調整編譯後的權重

直接來寫吧!
@layer 定義出 components 層,然後把剛剛的樣式挪進來:

@layer components {
  .box {
    @apply bg-gray-500 focus:ring-4 group-hover:text-gray-600 font-bold flex justify-center items-center rounded-md cursor-pointer outline-none w-20 h-20 text-3xl text-white;
  }
}

然後記得編譯~ 編譯完之後呢 ...

就正常了!

然後何謂元件呢? 我們這時候再多加一個方塊就知道了:

<div class="flex justify-evenly p-10 focus-within:bg-green-100 group">
  <box class="box bg-red-500 hover:bg-red-400 ring-red-300" tabindex="0">
    1
  </box>
  <box class="box bg-blue-500 hover:bg-blue-400 ring-blue-300" tabindex="1">
    2
  </box>
  
  <box class="box" tabindex="2">
    3
  </box>
</div>

上面只有使用 box 這個元件樣式,
不用編譯,我們直接來看畫面:

這樣表示我們三個元件都是繼承於元件樣式 .box
但還是可以透過 Tailwind 去客製化覆蓋掉原本的樣式
不需要用到任何一個 !important
 

carrotPoint 問爆兔兔

OK! 元件就這樣提取完畢了,其實過程算是很輕鬆又簡單的,接下來我就來大略解答一下你心中可能有的疑問。

「這樣不就又要取一些抽象的 class 名稱了嘛!不就又不能像兔兔你說的與視覺一致了嗎?」

沒錯,這麼做雖然看起來很打臉,但這是為了解決給非前端框架的人使用的方法,而且也可以避免掉像 Bootstrap 一樣要寫一堆很重要很重要的 !important 的窘境。

在前端框架之中,多半會使用這樣的方式:

<!-- 定義一個 Box 元件,Box.vue -->
<template>
  <div class="bg-gray-500 focus:ring-4 group-hover:text-gray-600 font-bold flex justify-center items-center rounded-md cursor-pointer outline-none w-20 h-20 text-3xl text-white" tabindex="0">
    ...
  </div>
</template>
<!-- 在頁面中使用 -->
<Box>
  1
</Box>

這樣就可以避免掉與設計與視覺不一致以及 class 名稱抽象的問題,所以之後我們也會用到前端框架哦!

「兔兔 ... 那個編譯真的很慢、世界久。 想退坑了怎麼辦,這樣好不方便!」

好~好~,我知道真的很慢 XD
但因為你並不會每天在增加新樣式和修改新樣式啊!

要解決這個問題,前面也聽我說過非常多次了對吧?
要靠 purgeJIT 模式!

purge 會檢查你所使用到的樣式,在編譯時把未使用到的樣式移除
因為少產生很多不必要的 class,雖然速度上不會變快,但所佔的空間會大大的縮小。(網頁載入時間可以縮短)

至於 JIT 模式則是基於 purge 去檢查所有有用到的樣式,
然後依照你所寫的內容動態新增樣式
而不是原本的刪去法,這速度快上太多太多了。

別擔心,我們很快就能夠加速和縮小了!
因為 purge 和 JIT 模式就是後面兩天的課題啦~
 

沒問題的話,今天大概就是這樣了!
明後兩天就是小還要更小,快還要更快、再更快!!!

carrotPoint 給你們的回家作業:


關於兔兔們:


 


( # 兔兔小聲說 )
 
 
 
我有說哦,一定是太小聲了你沒聽到。


上一篇
Day 13:「誰還在背字典?」- Tailwind IntelliSense 插件
下一篇
Day 15:「你真的不減肥嗎...?」- Tailwind 的生產環境優化
系列文
排版神器 Tailwind CSS~和兔兔一起快速上手漂亮的元件開發!32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
st474ddr
iT邦新手 2 級 ‧ 2021-11-03 13:46:57

請問兔兔大大
當中說到在前端框架多會使用的方式
是代表用一個vue檔就代表一個元件的意思嗎?
如 Box.vue 就只有 template 中撰寫該元件格式

所以在目錄配置上可能就會有專門 for tailwindcss 元件的資料夾對嗎?

我要留言

立即登入留言