使用 postcss-cva 來生成 cva 方法吧

Frame 3.png

使用 postcss-cva 來生成 cva 方法吧

什么是 cva

cva 全稱為 class-variance-authority, 它是一個非常適合制作那種肠套,創(chuàng)建控制Css變體方法的類庫墨缘,它非常的契合像 tailwindcss 這類的原子化思想竟闪。

在很多時候我們自己封裝組件, 尤其是使用原子化思想去編寫 css , 然后去封裝組件,用它就對了!

封裝示例

那么如何用它進(jìn)行封裝呢?我們以封裝一個直觀的 vue 組件 Button 為例:

<template>
  <button>
    <slot></slot>
  </button>
</template>

接下來我們要根據(jù)這個組件,傳入的 Props 來控制它的樣式漓骚,包括顏色種類蝌衔,大小,狀態(tài)蝌蹂,形狀等等噩斟。

那么假如使用樣式去控制這些,我們通常會這么寫:

<template>
  <button :class="className">
    <slot></slot>
  </button>
</template>

<script setup lang="ts">
import { computed } from 'vue';

function getButtonClass(props){
  let classNames = [/* base */]
  // do something with props like push, splice, unshift ...
  return classNames.join(' ')
}

const props = withDefaults(defineProps<{
  // ...
}>(), {
  // ... 
})
const className = computed(() => {
  return getButtonClass(props)
})
</script>

cva 就是幫助我們?nèi)ド蛇@個 getButtonClass 函數(shù)的一個方法孤个。

組成參數(shù)

一個 cva 的入?yún)⑻暝剩ǔ0?4 個部分: base,variants,compoundVariants,defaultVariants:

import { cva } from 'class-variance-authority'
//                     ?? base
const button = cva(['font-semibold', 'border', 'rounded'], {
  // ?? variants
  variants: {
    intent: {
      primary: ['bg-blue-500', 'text-white', 'border-transparent', 'hover:bg-blue-600'],
      secondary: ['bg-white', 'text-gray-800', 'border-gray-400', 'hover:bg-gray-100']
    },
    size: {
      small: ['text-sm', 'py-1', 'px-2'],
      medium: ['text-base', 'py-2', 'px-4']
    }
  },
  // ?? compoundVariants
  compoundVariants: [
    {
      intent: 'primary',
      size: 'medium',
      class: 'uppercase'
    }
  ],
  // ?? defaultVariants
  defaultVariants: {
    intent: 'primary',
    size: 'medium'
  }
})

button()
// => "font-semibold border rounded bg-blue-500 text-white border-transparent hover:bg-blue-600 text-base py-2 px-4 uppercase"
button({ intent: 'secondary', size: 'small' })
// => "font-semibold border rounded bg-white text-gray-800 border-gray-400 hover:bg-gray-100 text-sm py-1 px-2"

很多時候我們可以去構(gòu)造出這樣的函數(shù),來封裝我們的組件齐鲤。這會讓我們的代碼非常的直觀斥废,該控制樣式的就控制樣式,該控制行為的就控制行為给郊。所以用 cva 改造剛剛那個 vue Button 組件就很好牡肉。

但是假如我們項(xiàng)目不用原子化的Css類庫呢?或者我們希望在編寫 Css 時淆九,順便把 cva 函數(shù)給生成出來荚板,那么你就要來使用 postcss-cva 了。

postcss-cva 的功能

postcss-cva 是一個基于 css ast 分析的 postcss 插件吩屹。

它可以把你編寫的 Css 注釋,給轉(zhuǎn)化成 cva 函數(shù)拧抖。

Css 示例

來看一個簡單的例子煤搜,在 Button 組件的封裝過程中,寫下了以下的 Css

/* @meta path="./buttonClass" */
/* @dv size="md" */
.btn {
  /* @b */
  font-size: 16px;
  background: gray;
  border-radius: 4px;
}

.btn-primary {
  /* @v type="primary" */
  background: blue;
  color: white;
}

.btn-secondary {
  /* @v type="secondary" */
  font-size: 22px;
  color: yellow;
}

.btn-disabled {
  /* @cv type="primary" size="xs" */
  cursor: not-allowed;
}

.btn-md {
  /* @v size="md" */
  padding: 6px 10px;
  font-size: 16px;
}

.btn-xs {
  /* @v size="xs" */
  padding: 2px 6px;
  font-size: 14px;
}

.btn-sm {
  /* @v size="sm" */
  padding: 4px 8px;
  font-size: 12px;
}

原子化設(shè)計(jì)

在其中我們定義了:

  • 它的基礎(chǔ)類: base: .btn
  • 它的變種類: variants:
    • .btn-primary,.btn-secondary 來控制顏色種類
    • .btn-md,.btn-xs,.btn-sm 來控制大小
    • 更多的來控制唧席,形狀或者其他等等
  • 它的復(fù)合變種: compoundVariants: .btn-disabled (當(dāng)滿足傳入?yún)?shù) type="primary" size="xs" 時會觸發(fā))
  • 它的默認(rèn)變種: defaultVariants: size="md"(默認(rèn)什么參數(shù)都不傳的情況下使用 size="md")

注釋參考

然后依照 postcss-cva 的注釋參考:

keyword target type description
@b base node add current node selector to base
@gb base global define base
@v variants node add current node selector to variants
@gv variants global define variants
@cv compoundVariants node add current node selector to compoundVariants
@gcv compoundVariants global define defaultVariants
@dv defaultVariants global define defaultVariants
@meta meta global define metadata

通過添加相對應(yīng)的注釋擦盾,我們定義了所有的變種。

defined by @meta path="./buttonClass"

同時也定義了 cva 函數(shù)的文件輸出目錄為淌哟,當(dāng)前 Button.vue 文件所在目錄下的 buttonClass.ts 文件 (默認(rèn)格式為ts)

生成cva函數(shù)

這樣迹卢,再我們主運(yùn)行函數(shù),引入 vue 組件/ 注釋所在css文件時徒仓,一個 cva 函數(shù)就被生成了出來:

import { cva, VariantProps } from "class-variance-authority";
const index = cva(["btn"], {
  variants: {
    "type": {
      "primary": ["btn-primary"],
      "secondary": ["btn-secondary"]
    },
    "size": {
      "md": ["btn-md"],
      "xs": ["btn-xs"],
      "sm": ["btn-sm"]
    }
  },
  compoundVariants: [{
    "class": ["btn-disabled"],
    "type": ["primary"],
    "size": ["xs"]
  }],
  defaultVariants: {
    "size": "md"
  }
});
export type Props = VariantProps<typeof index>;
export default index;

然后腐碱,我們就可以直接引入進(jìn)行封裝了!

<template>
  <button :class="className">
    <slot>postcss-cva</slot>
  </button>
</template>

<script setup lang="ts">
import { computed } from 'vue';
import buttonClass, { Props as ButtonProps } from './buttonClass'

const props = withDefaults(defineProps<{
  // ButtonProps
  type?: 'primary' | 'secondary',
  size?: 'md' | 'sm' | 'xs'
}>(), {})
const className = computed(() => {
  return buttonClass(props)
}) 
</script>

是不是非常的簡單呢掉弛?

postcss-cva 能夠讓你在設(shè)計(jì)和編寫 css 的時候症见,就把 cva 函數(shù)給規(guī)劃好了。

現(xiàn)在你不但可以直接把它作為一個外置的 postcss 插件來使用殃饿,而且已經(jīng)被集成到了
IceStack 里面谋作。

趕快用它來管理和生成你的 Css UI 吧。

Refers

IceStack

postcss-cva

cva.style

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末乎芳,一起剝皮案震驚了整個濱河市遵蚜,隨后出現(xiàn)的幾起案子帖池,更是在濱河造成了極大的恐慌,老刑警劉巖吭净,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件睡汹,死亡現(xiàn)場離奇詭異,居然都是意外死亡攒钳,警方通過查閱死者的電腦和手機(jī)帮孔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來不撑,“玉大人文兢,你說我怎么就攤上這事』烂剩” “怎么了姆坚?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長实愚。 經(jīng)常有香客問我兼呵,道長,這世上最難降的妖魔是什么腊敲? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任击喂,我火速辦了婚禮,結(jié)果婚禮上碰辅,老公的妹妹穿的比我還像新娘懂昂。我一直安慰自己,他們只是感情好没宾,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布凌彬。 她就那樣靜靜地躺著,像睡著了一般循衰。 火紅的嫁衣襯著肌膚如雪铲敛。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天会钝,我揣著相機(jī)與錄音伐蒋,去河邊找鬼。 笑死迁酸,一個胖子當(dāng)著我的面吹牛咽弦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播胁出,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼型型,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了全蝶?” 一聲冷哼從身側(cè)響起闹蒜,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤寺枉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后绷落,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體姥闪,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年砌烁,在試婚紗的時候發(fā)現(xiàn)自己被綠了筐喳。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡函喉,死狀恐怖避归,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情管呵,我是刑警寧澤梳毙,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站捐下,受9級特大地震影響账锹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜坷襟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一奸柬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧婴程,春花似錦鸟缕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽授段。三九已至蹲蒲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間侵贵,已是汗流浹背届搁。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留窍育,地道東北人卡睦。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像漱抓,于是被迫代替她去往敵國和親表锻。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容