數(shù)據(jù)綁定的一個(gè)常見(jiàn)需求場(chǎng)景是操縱元素的 CSS class 列表和內(nèi)聯(lián)樣式。
因?yàn)?class
?和?style
?都是 attribute,我們可以和其他 attribute 一樣使用?v-bind
?將它們和動(dòng)態(tài)的字符串綁定。
但是,在處理比較復(fù)雜的綁定時(shí),通過(guò)拼接生成字符串是麻煩且易出錯(cuò)的。
因此,Vue 專門(mén)為?class
?和?style
?的?v-bind
?用法提供了特殊的功能增強(qiáng)。
除了字符串外,表達(dá)式的值也可以是對(duì)象或數(shù)組。
能動(dòng)態(tài)的修改各類樣式
提要:
- v-bind:指令會(huì)將普通屬性的值變?yōu)楸磉_(dá)值
- 使用
v-bind
指令的class
屬性值不再是字符串,而是表達(dá)式。 表達(dá)式里的className
不是一個(gè)普通的字符,而是一個(gè)變量,Vue
實(shí)例data
屬性中的數(shù)據(jù)。 - v-bind 在處理 class 和 style 時(shí), 表達(dá)式除了可以使用字符串之外,還可以是對(duì)象或數(shù)組。
- v-bind:class?可以簡(jiǎn)寫(xiě)為?:class。
v-bind
指令可以讓我們將屬性值關(guān)聯(lián)到Vuedata
數(shù)據(jù)中,這樣的屬性,我們稱作為屬性的動(dòng)態(tài)綁定。
屬性的動(dòng)態(tài)綁定比較符合vue以數(shù)據(jù)為驅(qū)動(dòng)的模式,如果需要修改那個(gè)屬性值,就可以直接通過(guò)修改Vue
數(shù)據(jù)即可。
注意:
動(dòng)態(tài)屬性綁定, 在我們需要的時(shí)候在使用,如果一個(gè)屬性的是是固定的,并不會(huì)在未來(lái)發(fā)生改變,就沒(méi)有必要?jiǎng)討B(tài)綁定屬性.
但在屬性動(dòng)態(tài)綁定過(guò)程中有兩個(gè)屬性比較特殊,這兩個(gè)屬性就是class 和style屬性,
在將 v-bind
用于 class
和 style
時(shí),Vue.js 做了專門(mén)的增強(qiáng)。
表達(dá)式結(jié)果的類型除了字符串之外,還可以是對(duì)象或數(shù)組。
用法示例
<h2 :class="msg">Hello World</h2>
使用動(dòng)態(tài)綁定指令, 那么此時(shí)class后面的引號(hào)不再是字符串,而是一個(gè)JavaScript
表達(dá)式。
?msg
也就成為了一個(gè)變量,因此此時(shí)h2標(biāo)簽的類名不是字符串msg
, 而是data數(shù)據(jù)中msg
中的值、
演示代碼
<script src="https://unpkg.com/vue@next"></script>
<div id="app">
<!-- 未使用動(dòng)態(tài)綁定的class屬性 -->
<div class="msg">hello world</div>
<!-- 使用v-bind 動(dòng)態(tài)綁定class屬性 -->
<div :class="msg">你好! Vue</div>
</div>
<script>
const App = {
data() {
return {
msg: 'nbox',
}
},
}
const app = Vue.createApp(App);
app.mount("#app");
</script>
<style>
.nbox {
color: red;
}
</style>
瀏覽器執(zhí)行效果
hello world 你好! Vue
??Class
屬性綁定
我們可以為?v-bind:class?設(shè)置一個(gè)對(duì)象,從而動(dòng)態(tài)的切換?class:
<div :class="{ 'active': isActive }"></div>
如果isActive為真,則在瀏覽器中渲染如下
<div class="active"></div>
語(yǔ)法說(shuō)明:
- 上面的語(yǔ)法表示:
active
這個(gè) 類名是否存在 將取決于數(shù)據(jù)屬性isActive
的 布爾特性。 - 如果
isActive
的值為true
, 那么div
將有類名active
否則,div
沒(méi)有box
類名 - 需要注意,此時(shí)
active
就是一個(gè)類名,并不是vue中的數(shù)據(jù)屬性
多個(gè)對(duì)象
<div :class="{'active' : isActive, 'text-danger' : hasError}"></div>
瀏覽器渲染
<div class="active text-danger"></div>
與普通的 class 屬性共存
<div class="static" :class="{ 'active' : isActive, 'text-danger' : hasError }"> </div>
瀏覽器渲染
<div class="static active text-danger"></div>
錯(cuò)誤示例,下列兩個(gè)代碼不會(huì)生效
<h2 :class="msg box">Hello World</h2>
<h2
:class="isTrue ? msg : ''"
:class="flag ? 'haha' : ''"
>你好</h2>
class綁定對(duì)象
如果您的class屬性較多,我推薦您綁定對(duì)象,以便您的操作和代碼的整潔性
<div id="app">
<div :class="classObject"></div>
</div>
const app = {
data() {
return {
classObject: {
'active': false,
'text-danger': true
}
}
}
}
瀏覽器渲染
<div class="text-danger"></div>
綁定一個(gè)返回對(duì)象的計(jì)算屬性。這是一個(gè)常用且強(qiáng)大的模式
<div id="app">
<div :class="classObject"></div>
</div>
const app = {
data() {
return {
isActive: true,
error: false,
}
},
computed: {
classObject() {
return {
active: this.isActive,
'text-danger': !this.error,
}
}
}
}
瀏覽器渲染
<div class="active text-danger"></div>
class綁定數(shù)組(方法一)
<div id="app">
<div class="static" :class="[activeClass, errorClass]"></div>
</div>
const app = {
data() {
return {
activeClass: 'active',
errorClass: 'text-danger'
}
}
}
class綁定數(shù)組(方法二)
<div :class="classObject"></div>
const App = {
data() {
return {
classObject: ["static", "active", { "text-danger": true }],
}
},
}
以上兩種方法,瀏覽器渲染均為
<div class="static active text-danger"></div>
使用三元表達(dá)式來(lái)切換列表中的 class
<div id="app">
<div :class="[isActive ? activeClass : '', errorClass]"></div>
</div>
const app = {
data() {
return {
isActive: false,
activeClass: 'active',
errorClass: 'text-danger'
}
}
}
瀏覽器渲染為
<div class="text-danger"></div>
在代碼isActive ? activeClass : ''
中,因?yàn)?code>isActive是假,表達(dá)式的值為第三個(gè),為空值,當(dāng)isActive
為真時(shí),表達(dá)式的值為第二個(gè),即為activeClass
。
??style(內(nèi)聯(lián)樣式)
動(dòng)態(tài)綁定style屬性說(shuō)明:
- 如果使用動(dòng)態(tài)綁定屬性方法綁定行內(nèi)樣式,那么style屬性值將不再是字符串,而是表達(dá)式,
- 動(dòng)態(tài)綁定style的值既然是表達(dá)式,那么就可以在表達(dá)式中使用對(duì)象.
- 如果值為對(duì)象,那么對(duì)象的屬性名則為CSS樣式屬性, 值為樣式的值。
- 注意,此時(shí)對(duì)象中的屬性值,可以是確定的樣式值,也可以是vue的數(shù)據(jù)變量,
- 因此有些值不能再像
style
標(biāo)簽中一樣書(shū)寫(xiě),例如50px
,以前使用不加引號(hào),現(xiàn)在必須加引號(hào)
對(duì)象寫(xiě)法關(guān)于值的問(wèn)題
如果使用動(dòng)態(tài)綁定屬性style里的對(duì)象值不加引號(hào), 就會(huì)有如下的問(wèn)題:
<h2 :style="{color:red,font-size:30px}">Hello World</h2>
上面的這種寫(xiě)法就會(huì)報(bào)錯(cuò),?red
和30px
會(huì)被當(dāng)做變量去Vue data
屬性中找對(duì)應(yīng)的數(shù)據(jù), 但是找不到就報(bào)錯(cuò)
正確的寫(xiě)法應(yīng)該是這樣的
<h2 :style="{color:'red',fontSize:'30px'}">Hello World</h2>
也能正確顯示結(jié)果, 但是要注意字符串嵌套問(wèn)題

對(duì)象寫(xiě)法的屬性問(wèn)題:
相信通過(guò)剛才的例子,你也發(fā)現(xiàn)了,我們發(fā)font-size
的寫(xiě)法改為了fontSize
.
因?yàn)镃SS 屬性名可以用駝峰式 (camelCase) 或短橫線分隔 (kebab-case) 都可以:
因此,在普通的style
屬性中一下兩種寫(xiě)法都可以
<!-- 駝峰式 (camelCase) 寫(xiě)法 --->
<h2 style="color:red;fontSize:30px;">Hello World</h2>
<!-- 短橫線分隔 (kebab-case --->
<h2 style="color:red;font-size:30px;">Hello World</h2>
兩種處理方法:
- 駝峰式 (camelCase)
- 如果要使用連字符, 就需要添加雙引號(hào), 將屬性變成字符串的寫(xiě)法
因此動(dòng)態(tài)綁定需要如下寫(xiě)法
<!-- 駝峰式 (camelCase) 寫(xiě)法 --->
<h2 :style="{color:'red', fontSize:'30px'}">Hello World</h2>
<!-- 短橫線分隔 (kebab-case) 但是要加引號(hào) --->
<h2 :style="{color:'red', 'font-size' :'30px'}">Hello World</h2>
推薦用駝峰寫(xiě)法, 對(duì)象的值也可以是變量
示例代碼
<div id="app">
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }">菜鳥(niǎo)教程</div>
</div>
<script>
const app = {
data() {
return {
activeColor: 'red',
fontSize: 30
}
}
}
Vue.createApp(app).mount('#app')
</script>
瀏覽器渲染
<div style="color: red; font-size: 30px;">菜鳥(niǎo)教程</div>
style綁定對(duì)象(推薦)
代碼
<div id="app">
<div :style="styleObject">菜鳥(niǎo)教程</div>
</div>
<script>
const app = {
data() {
return {
styleObject: {
color: "red",
fontSize: "30px"
}
}
}
}
Vue.createApp(app).mount('#app')
瀏覽器渲染
<div style="color: red; font-size: 30px;">菜鳥(niǎo)教程</div>
同樣的,如果樣式對(duì)象需要更復(fù)雜的邏輯,也可以使用返回樣式對(duì)象的計(jì)算屬性。
動(dòng)態(tài)修改樣式
代碼
<script src="https://unpkg.com/vue@next"></script>
<div id="app">
<h2 :style="styleObject">Hello World</h2>
<button @click="changColor">點(diǎn)擊切換顏色</button>
</div>
<script>
const App = {
data() {
return {
styleObject: {
color: "red",
fontSize: "30px"
}
}
},
methods: {
changColor() {
this.styleObject.color = this.styleObject.color == "red" ? "skyblue" : "red"
}
}
}
const app = Vue.createApp(App);
app.mount("#app");
</script>
瀏覽器運(yùn)行效果
Hello World
style綁定數(shù)組
可以擴(kuò)展對(duì)象的用法,給動(dòng)態(tài)屬性的值綁定為數(shù)組,數(shù)組中就可以使用多組樣式對(duì)象來(lái)綁定CSS樣式。
這些對(duì)象會(huì)被合并后渲染到同一元素上:
代碼
<div id="app">
<div :style="[baseStyles, overridingStyles]">菜鳥(niǎo)教程</div>
</div>
<script>
const app = {
data() {
return {
baseStyles: {
color: 'green',
fontSize: '30px'
},
overridingStyles: {
'font-weight': 'bold'
}
}
}
}
Vue.createApp(app).mount('#app')
瀏覽器渲染
<div style="color: green; font-size: 30px; font-weight: bold;">菜鳥(niǎo)教程</div>
注意:
當(dāng)?v-bind:style?使用需要特定前綴的 CSS 屬性時(shí),如 transform ,Vue.js 會(huì)自動(dòng)偵測(cè)并添加相應(yīng)的前綴。
自動(dòng)前綴
當(dāng)你在?:style
?中使用了需要瀏覽器特殊前綴的 CSS 屬性時(shí),Vue 會(huì)自動(dòng)為他們加上相應(yīng)的前綴。Vue 是在運(yùn)行時(shí)檢查該屬性是否支持在當(dāng)前瀏覽器中使用。如果瀏覽器不支持某個(gè)屬性,那么將測(cè)試加上各個(gè)瀏覽器特殊前綴,以找到哪一個(gè)是被支持的。
多重值
可以為 style 綁定中的 property 提供一個(gè)包含多個(gè)值的數(shù)組,常用于提供多個(gè)帶前綴的值,例如:
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
這樣寫(xiě)只會(huì)渲染數(shù)組中最后一個(gè)被瀏覽器支持的值。在本例中,如果瀏覽器支持不帶瀏覽器前綴的 flexbox,那么就只會(huì)渲染 display: flex。
??組件
單個(gè)根元素的自定義組件
當(dāng)你在帶有單個(gè)根元素的自定義組件上使用 class 屬性時(shí),這些 class 將被添加到該元素中。此元素上的現(xiàn)有 class 將不會(huì)被覆蓋。
<div id="app">
<runoob class="classC classD"></runoob>
</div>
app.component('runoob', {
template: '<h1 class="classA classB">I like runoob!</h1>'
})
瀏覽器渲染
<h1 class="classA classB classC classD">I like runoob!</h1>
帶數(shù)據(jù)綁定,此元素上的現(xiàn)有 class 將不會(huì)被覆蓋。
<my-component :class="{ active: isActive }"></my-component>
渲染(isActive
為真)
<p class="active">Hi</p>
多個(gè)根元素
如果你的組件有多個(gè)根元素,你需要定義哪些部分將接收這個(gè)類。可以使用?$attrs?組件屬性執(zhí)行此操作:
<script src="https://unpkg.com/vue@next"></script>
<style>
.classA {
color: red;
font-size:30px;
}
</style>
<div id="app">
<runoob class="classA"></runoob>
</div>
<script>
const app = Vue.createApp({})
app.component('runoob', {
template: `
<p :class="$attrs.class">I like runoob!</p>
<span>這是一個(gè)子組件</span>
`
})
app.mount('#app')
</script>
注意:template 中?`?是反引號(hào),不是單引號(hào)?‘。
瀏覽器渲染
<div id="app">
<p class="classA">I like runoob!</p>
<span>這是一個(gè)子組件</span></div>
拓展想象
若是配合CSS變量,豈不是有無(wú)限可能