改變樣式是我們實(shí)際開發(fā)中最常做的事情。
諸如在css中,我們添加鼠標(biāo)滑入滑出效果添加不同的樣式。
諸如在js中,我們根據(jù)某個(gè)條件,或者觸發(fā)某個(gè)方法,去動(dòng)態(tài)改變某個(gè)樣式。
那么,在vue中,我們更能很輕松的達(dá)到這點(diǎn)。
看下常見的幾種情景:
- 情景一:我們需要根據(jù)某個(gè)變量是否存在(觸發(fā)),去動(dòng)態(tài)添加樣式
描述:當(dāng)我們點(diǎn)擊按鈕觸發(fā)了某個(gè)條件,我們需要給對(duì)應(yīng)的元素添加激活效果
<div
class="flip"
:style="{
background:變量?'red':'black'
}"
/div >
這里我們通過三目判斷某個(gè)觸發(fā)條件的變量是否為true以此來添加不同的樣式(當(dāng)然也可以動(dòng)態(tài)綁定class,來添加不同的類名,實(shí)現(xiàn)不同的效果)
- 情景二:我們封裝組件,希望外界可以自定義傳入實(shí)現(xiàn)不同的樣式
描述:通過props定義樣式值,外界可自定義傳入改變,不傳入則使用默認(rèn)值
<template>
<div class="rd-flop">
<div
class="flip"
:style="{
width: width,
height: height,
lineHeight: lineHeight,
margin: margin,
fontSize: `${fontSize}px`,
fontWeight: fontWeight,
border: border,
borderRadius: `${borderRadius}px`,
boxShadow: boxShadow,
}"
>
</div>
</div>
</template>
<script>
export default {
name: '',
props: {
width: { type: String, default: '36px' }, // 寬度
height: { type: String, default: '46px' }, // 高度
lineHeight: { type: String, default: '46px' }, // 高度
margin: { type: String, default: '2px' }, // 間距
fontSize: { type: Number, default: 16 }, // 字體大小
fontWeight: { type: Number, default: 900 }, // 字體加粗(100-500為不加粗,600-900加粗)
border: { type: String, default: '1px solid transparent' }, // 邊框
borderRadius: { type: Number, default: 0 }, // 圓角
boxShadow: { type: String, default: '0 0 6px rgba(0, 0, 0, 0.5)' }, // 容器陰影
}
};
</script>
上面的組件,我們?cè)偈褂玫臅r(shí)候,當(dāng)我們不傳入值的時(shí)候,也能正常顯示默認(rèn)值達(dá)到默認(rèn)效果,我們也可以傳入對(duì)應(yīng)的值達(dá)到不同的復(fù)用效果
- 情景三:動(dòng)態(tài)綁定實(shí)現(xiàn)改變偽元素等樣式
描述:以上樣式都是我們最普通的樣式,但是我們?nèi)绾瓮ㄟ^綁定樣式改變偽元素(::before、::after)、激活、滑入等復(fù)雜的樣式呢?看下下面的示例吧:
<template>
<div class="rd-flop">
<div class="rd-clock-card" v-if="currData" ref="rdFlop">
<div
class="flip"
:style="{
width: width,
height: height,
lineHeight: lineHeight,
margin: margin,
fontSize: `${fontSize}px`,
fontWeight: fontWeight,
border: border,
borderRadius: `${borderRadius}px`,
boxShadow: boxShadow,
'--threeColumnMargin': threeColumnMargin,
}"
v-for="(item, index) in currValue.length"
:key="index"
>
<div
class="digital front"
:style="{
'--pseudoElementColor': pseudoElementColor,
'--pseudoElementBg': pseudoElementBg,
'--pseudoElementBorder': pseudoElementBorder,
'--pseudoElementTopBorderRadius': pseudoElementTopBorderRadius,
'--pseudoElementBotBorderRadius': pseudoElementBotBorderRadius,
'--pseudoElementBoxShadow': pseudoElementBoxShadow,
}"
data-number="0"
></div>
<div
class="digital back"
:style="{
'--pseudoElementColor': pseudoElementColor,
'--pseudoElementBg': pseudoElementBg,
'--pseudoElementBorder': pseudoElementBorder,
'--pseudoElementTopBorderRadius': pseudoElementTopBorderRadius,
'--pseudoElementBotBorderRadius': pseudoElementBotBorderRadius,
'--pseudoElementBoxShadow': pseudoElementBoxShadow,
}"
data-number="1"
></div>
</div>
</div>
<p :style="{ margin: titleMargin, fontSize: `${titleFontSize}px` }">
{{ category }}
</p>
</div>
</template>
<script>
export default {
name: '',
props: {
title: String, // 標(biāo)題
width: { type: String, default: '36px' }, // 寬度
height: { type: String, default: '46px' }, // 高度
lineHeight: { type: String, default: '46px' }, // 高度
margin: { type: String, default: '2px' }, // 間距
threeColumnMargin: { type: String, default: '5px 30px 5px 5px' }, // 第三列間距(數(shù)字三個(gè)一組)
fontSize: { type: Number, default: 16 }, // 字體大小
fontWeight: { type: Number, default: 900 }, // 字體加粗(100-500為不加粗,600-900加粗)
border: { type: String, default: '1px solid transparent' }, // 邊框
borderRadius: { type: Number, default: 0 }, // 圓角
boxShadow: { type: String, default: '0 0 6px rgba(0, 0, 0, 0.5)' }, // 容器陰影
pseudoElementColor: { type: String, default: '#fff' }, // 偽元素字體顏色
pseudoElementBg: { type: String, default: '#3354e2' }, // 偽元素背景
pseudoElementBorder: { type: String, default: '1px solid #666' }, // 偽元素邊框
pseudoElementTopBorderRadius: { type: String, default: '0 0 0 0' }, // 偽元素上半部分圓角
pseudoElementBotBorderRadius: { type: String, default: '0 0 0 0' }, // 偽元素下半部分圓角
pseudoElementBoxShadow: {
type: String,
default: '0 -2px 6px rgba(255, 255, 255, 0.3)',
}, // 偽元素容器陰影
titleMargin: { type: String, default: '20px 0 0 0' }, // 標(biāo)題間距
titleFontSize: {
type: Number,
default: 30,
}, // 標(biāo)題字體大小
},
};
</script>
<style scoped>
.rd-clock-card .flip .digital::before,
.rd-clock-card .flip .digital::after {
position: absolute;
content: attr(data-number);
left: 0;
right: 0;
color: var(--pseudoElementColor);
background: var(--pseudoElementBg);
overflow: hidden;
perspective: 160px;
}
.flip:nth-of-type(3n) {
margin: var(--threeColumnMargin) !important;
}
.rd-clock-card .flip .digital::before {
top: 0;
bottom: 50%;
border-bottom: var(--pseudoElementBorder);
border-radius: var(--pseudoElementTopBorderRadius);
}
.rd-clock-card .flip .digital::after {
top: 50%;
bottom: 0;
line-height: 0;
border-radius: var(--pseudoElementBotBorderRadius);
}
.rd-clock-card .flip.running .front::before {
transform-origin: center bottom;
animation: frontFlipDown 1s ease-in-out;
box-shadow: var(--pseudoElementBoxShadow);
backface-visibility: hidden;
}
</style>
上述示例中,我們?cè)趯?duì)應(yīng)的樣式處,通過 var(--自定義命名) 的方式定義變量(括號(hào)里面是兩條杠,別寫錯(cuò)了),在vue的標(biāo)簽處通過 '--var中定義的命名': props中對(duì)應(yīng)的樣式變量 就可以改變對(duì)應(yīng)的樣式。
當(dāng)然了,功能遠(yuǎn)不止于此,我們?cè)谑褂靡恍┕瞮i庫(kù)(比如element ui)時(shí),它的一些標(biāo)簽都是自動(dòng)生成的,比如我們只引入了 el-dropdown 下拉菜單,但是我們通過在控制臺(tái)查閱發(fā)現(xiàn)內(nèi)部可能嵌套生成很多標(biāo)簽,這時(shí)我們想改變內(nèi)部嵌套的子元素的樣式,就沒辦法直接給父元素綁定諸如寬、高的方式,我們可以找到對(duì)應(yīng)的類名樣式,通過 var的方式(參考如下)
.VideoSurveillance .listArea .videoList .el-tree .el-tree-node__content {
height: var(--itemGap);
line-height: var(--itemGap);
position: relative;
}
當(dāng)然了,考慮用法前可以參考下兼容性
好了,如上就是vue中動(dòng)態(tài)改變特殊樣式時(shí)的技巧。
如有問題,請(qǐng)指出,接收批評(píng)。