Day 14:「怎麽跟阿嬷的裹脚布一样啦!」- 提取成元件

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-00 引言

>>:  Day-01 前言

Day 16:axios 先封装,API 轻松发

上篇我们在单一元件内使用 axios 发送 API,但如果专案规模愈来愈大,需要同时管理多个功能的 ...

Day30-还想学更多吗?推荐 Youtube 上面免费的 React 学习资源

终於铁人赛也到了尾声,在这三十天为了完成技术文章,查询了不少的资料当作参考,其中也包括了在 yout...

[DAY2]建立LINE BOT

第一步: 进入LINE DEVLOPERS网页: https://developers.line.b...

[DAY06] 开始用 Notebook 在 Azure Machine Learing 上写程序

DAY06 开始用 Notebook 在 Azure Machine Learing 上写程序 我们...

[访谈] APCS x 竞程沙漠 Howard

今天邀请到同系同级的 Howard 来分享他在高中学习程序的经历和对於 APCS 的想法~ 程序学习...