【譯】Vue實用筆記(二十七):在Vue組件中通過自定義css屬性來自定義主題

作者: Cesar Alberca (@cesalberca), a frontend developer at Autentia that have worked with Vue professionally for 2 years and counting. He’s also done projects in React and Angular and he’s passionate about good practices and testing.

I met Cesar at the last Codemotion Madrid conference and I have to say he’s a really cool guy with lots of potential! Don’t expect too little from this tip ??.

正文開始


大家好哇旗扑!VueDoes的主旨是創(chuàng)建通用仔役, 靈活穩(wěn)定的組件摄悯。準備好了嗎趾徽?出發(fā)嘍啥供!

先看一個簡單的button

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

<script>
export default {
  name: "AppButton",
};
</script>

<style scoped>
button {
  border: 4px solid #41b883;
  padding: 12px 24px;
  transition: 0.25s ease-in-out all;
}

button:hover {
  color: white;
  background-color: #41b883;
}
</style>

我們希望一個組件越通用越好忘伞,這樣我們就可以在不同的網(wǎng)站重用它了撮执。但是如何編寫一個這樣的組件呢微峰?

首先,我們假設(shè)不只是需要一段文本內(nèi)容抒钱。如果我們想要不同的內(nèi)容蜓肆,例如e <strong></strong> 或者一個icon颜凯?最好的解決辦法是實用slots

讓我們繼續(xù)剛才的話題仗扬,通常症概,我們的經(jīng)驗是使用 scoped ,在不同的組件中定義CSS早芭。但是彼城,如果我們需要一些全局的配置CSS呢?這樣我們就違反了DRY規(guī)則退个。如果我們需要改變主色募壕,我們不得不改變?nèi)魏我粋€硬編碼的地方。那么解決方案是神馬呢语盈?實用custom properties 舱馅。

<style scoped>
:root {
  --primary-color: #41b883;
  --on-primary-color: white;

  --small-spacing: 12px;
  --normal-spacing: calc(var(--small-spacing) * 2);
}

button {
  border: 4px solid var(--primary-color);
  padding: var(--small-spacing) var(--normal-spacing);
  transition: 0.25s ease-in-out all;
}

button:hover {
  color: var(--on-primary-color);
  background-color: var(--primary-color);
}
</style>

我們會在另外一個文件中自定義 :root 選擇器,但是為了清楚起見刀荒,我們現(xiàn)在當前組件的文件中定義代嗤。

顏色和間距在web設(shè)計中經(jīng)常改變的內(nèi)容,我們需要保證不因他們的改變而改變照棋。

通過改變屬性來影響所有的組件從而來達到重用的目的资溃,會使得我們的組件非常靈活。

那么烈炭,如果定義一個網(wǎng)站主題呢溶锭?我們可以實用免聲明的自定義屬性。先解釋一下:

<style scoped>
button {
  border: 4px solid var(--button-border-color, var(--primary-color));
  padding: var(--small-spacing) var(--normal-spacing);
  transition: 0.25s ease-in-out all;
}

button:hover {
  color: var(--button-hover-text-color, var(--on-primary-color));
  background-color: var(--button-hover-background-color, var(--primary-color));
}
</style>

我們在哪里定義--button-border-color, --button-hover-text-color and --button-hover-background-color這些變量呢符隙?這就是技巧了趴捅,我們沒有定義。

我們實用了一個為定義的自定義屬性但是給它了一個默認值霹疫。所以拱绑,如果運行時,任何一個屬性沒有被定義的話丽蝎,它就會回溯到它的默認值猎拨。

這意味著,我們可以從外面定義這些屬性屠阻。

<template>
  <AppButton class="custom-theme">Hello VueDose!</AppButton>
</template>

<style scoped>
.custom-theme {
  --button-border-color: pink;
  --button-hover-background-color: rgb(206, 161, 195);
}
</style>

這樣非常靈活红省,但可能太靈活了。我們不想暴露太多細節(jié)給使用者国觉。這個使用者可能想要自己設(shè)定一個主色來代替原來的創(chuàng)建一個新的主題吧恃。但是這個Button需要知道,它被設(shè)置了什么參數(shù)麻诀。所以讓我們來自定義屬性和主題痕寓。

<template>
  <button :style="getTheme"><slot/></button>
</template>

<script>
export default {
  name: "AppButton6",
  props: {
    theme: String,
    validator: (theme) => ['primary', 'secondary'].includes(theme)
  },
  computed: {
    getTheme() {
      const createButtonTheme = ({
        borderColor,
        hoverTextColor,
        hoverBackgroundColor
      }) => ({
        '--button-border-color': borderColor,
        '--button-hover-text-color': hoverTextColor,
        '--button-hover-background-color': hoverBackgroundColor
      })

      const primary = createButtonTheme({
        borderColor: 'var(--primary-color)',
        hoverTextColor: 'var(--on-primary-color)',
        hoverBackgroundColor: 'var(--primary-color)'
      })

      const secondary = createButtonTheme({
        borderColor: 'var(--secondary-color)',
        hoverTextColor: 'var(--on-secondary-color)',
        hoverBackgroundColor: 'var(--secondary-color)'
      })

      const themes = {
        primary,
        secondary
      }

      return themes[this.theme]
    }
  }
};
</script>

So we can do this easily:

<AppButton theme="secondary">Hello VueDose!</AppButton>

And finally. All the cool kids nowadays are doing dark themes right?

<template>
  <main class="wrapper" :class="mode">
    <AppButton @click.native="toggleTheme" theme="secondary">
      Click me to change to dark mode!
    </AppButton>
  </main>
</template>

<script>
import AppButton from "./components/AppButton";

export default {
  name: "App",
  data: () => ({
    mode: 'light'
  }),
  components: {
    AppButton
  },
  methods: {
    toggleTheme() {
      this.mode = this.mode === 'light' ? 'dark' : 'light'
    }
  }
};
</script>
<style scoped>
.light {
  --background-color: white;
  --on-background-color: #222;
}

.dark {
  --background-color: #222;
  --on-background-color: white;
}

.wrapper {
  transition: 1s ease-in-out background-color;
  background-color: var(--background-color);
  color: var(--on-background-color);
}
</style>

我們可以切換 --background-color--on-background-color這兩個來達到創(chuàng)建新主題的目的傲醉。
以上就是全部內(nèi)容了。感謝你讀完了全部內(nèi)容呻率。點擊 this CodeSandbox!

Here it goes today’s tip!

Remember you can read this tip online (with copy/pasteable code), and don’t forget to share VueDose with your colleagues, so they also know about these tips as well!

See you soon.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末硬毕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子筷凤,更是在濱河造成了極大的恐慌昭殉,老刑警劉巖苞七,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件藐守,死亡現(xiàn)場離奇詭異,居然都是意外死亡蹂风,警方通過查閱死者的電腦和手機卢厂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來惠啄,“玉大人慎恒,你說我怎么就攤上這事∧於桑” “怎么了融柬?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長趋距。 經(jīng)常有香客問我粒氧,道長歧杏,這世上最難降的妖魔是什么型宝? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮挺尿,結(jié)果婚禮上翼雀,老公的妹妹穿的比我還像新娘饱苟。我一直安慰自己,他們只是感情好狼渊,可當我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布箱熬。 她就那樣靜靜地躺著,像睡著了一般狈邑。 火紅的嫁衣襯著肌膚如雪城须。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天官地,我揣著相機與錄音酿傍,去河邊找鬼。 笑死驱入,一個胖子當著我的面吹牛赤炒,可吹牛的內(nèi)容都是我干的氯析。 我是一名探鬼主播,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼莺褒,長吁一口氣:“原來是場噩夢啊……” “哼掩缓!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起遵岩,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤你辣,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后尘执,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體舍哄,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年誊锭,在試婚紗的時候發(fā)現(xiàn)自己被綠了表悬。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡丧靡,死狀恐怖蟆沫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情温治,我是刑警寧澤饭庞,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站熬荆,受9級特大地震影響舟山,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜惶看,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一捏顺、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧纬黎,春花似錦幅骄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至冠息,卻和暖如春挪凑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背逛艰。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工躏碳, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人散怖。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓菇绵,卻偏偏與公主長得像肄渗,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子咬最,可洞房花燭夜當晚...
    茶點故事閱讀 44,974評論 2 355

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

  • 8月14日翎嫡,離中元節(jié)還有最后一刻。 此時此刻永乌,在老家 恰巧惑申,一個間接的親人也剛剛?cè)ナ馈?明天出殯。 在靈魂深處翅雏,總...
    艷陽滿天閱讀 144評論 0 0
  • “十二兒”是一只可愛的金毛圈驼,我家的新成員。因為一次巧合的機會枚荣,爸爸的朋友轉(zhuǎn)給我們了一只快滿一歲的金毛碗脊,現(xiàn)在來說...
    馬鈴薯的媽閱讀 133評論 0 0
  • 瑜伽時的你~好美啼肩, 心晴伽園~瑜伽時的你橄妆,好好美, 美的晃的心晴忘了留影~~ 又要時時留影記錄你瑜伽始祈坠,瑜伽中害碾,瑜...
    心晴伽園閱讀 454評論 0 1
  • 從小到大我們都渴望擁有主角光環(huán) 輕輕松松就能夠得到一切喜歡的東西 能成為那些大人們口中的“別人家的孩子” 能像《來...
    Sdft閱讀 295評論 0 2
  • 在這家臺企工作的第四年,子公司的一把手-老大高升了赦拘,吃散伙飯那天老大哭了慌随,主管們哭了,小兵嘍嘍們也哭了躺同,該怎么形容...
    火色石榴花閱讀 261評論 0 0