作者: 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.