數據綁定的一個常見需求場景是操縱元素的 CSS class 列表和內聯樣式。
因為?class
?和?style
?都是 attribute,我們可以和其他 attribute 一樣使用?v-bind
?將它們和動態的字符串綁定。
但是,在處理比較復雜的綁定時,通過拼接生成字符串是麻煩且易出錯的。
因此,Vue 專門為?class
?和?style
?的?v-bind
?用法提供了特殊的功能增強。
除了字符串外,表達式的值也可以是對象或數組。
能動態的修改各類樣式
提要:
- v-bind:指令會將普通屬性的值變為表達值
- 使用
v-bind
指令的class
屬性值不再是字符串,而是表達式。 表達式里的className
不是一個普通的字符,而是一個變量,Vue
實例data
屬性中的數據。 - v-bind 在處理 class 和 style 時, 表達式除了可以使用字符串之外,還可以是對象或數組。
- v-bind:class?可以簡寫為?:class。
v-bind
指令可以讓我們將屬性值關聯到Vuedata
數據中,這樣的屬性,我們稱作為屬性的動態綁定。
屬性的動態綁定比較符合vue以數據為驅動的模式,如果需要修改那個屬性值,就可以直接通過修改Vue
數據即可。
注意:
動態屬性綁定, 在我們需要的時候在使用,如果一個屬性的是是固定的,并不會在未來發生改變,就沒有必要動態綁定屬性.
但在屬性動態綁定過程中有兩個屬性比較特殊,這兩個屬性就是class 和style屬性,
在將 v-bind
用于 class
和 style
時,Vue.js 做了專門的增強。
表達式結果的類型除了字符串之外,還可以是對象或數組。
用法示例
<h2 :class="msg">Hello World</h2>
使用動態綁定指令, 那么此時class后面的引號不再是字符串,而是一個JavaScript
表達式。
?msg
也就成為了一個變量,因此此時h2標簽的類名不是字符串msg
, 而是data數據中msg
中的值、
演示代碼
<script src="https://unpkg.com/vue@next"></script>
<div id="app">
<!-- 未使用動態綁定的class屬性 -->
<div class="msg">hello world</div>
<!-- 使用v-bind 動態綁定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>
瀏覽器執行效果

??Class
屬性綁定
我們可以為?v-bind:class?設置一個對象,從而動態的切換?class:
<div :class="{ 'active': isActive }"></div>
如果isActive為真,則在瀏覽器中渲染如下
<div class="active"></div>
語法說明:
- 上面的語法表示:
active
這個 類名是否存在 將取決于數據屬性isActive
的 布爾特性。 - 如果
isActive
的值為true
, 那么div
將有類名active
否則,div
沒有box
類名 - 需要注意,此時
active
就是一個類名,并不是vue中的數據屬性
多個對象
<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>
錯誤示例,下列兩個代碼不會生效
<h2 :class="msg box">Hello World</h2>
<h2
:class="isTrue ? msg : ''"
:class="flag ? 'haha' : ''"
>你好</h2>
class綁定對象
如果您的class屬性較多,我推薦您綁定對象,以便您的操作和代碼的整潔性
<div id="app">
<div :class="classObject"></div>
</div>
const app = {
data() {
return {
classObject: {
'active': false,
'text-danger': true
}
}
}
}
瀏覽器渲染
<div class="text-danger"></div>
綁定一個返回對象的計算屬性。這是一個常用且強大的模式
<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綁定數組(方法一)
<div id="app">
<div class="static" :class="[activeClass, errorClass]"></div>
</div>
const app = {
data() {
return {
activeClass: 'active',
errorClass: 'text-danger'
}
}
}
class綁定數組(方法二)
<div :class="classObject"></div>
const App = {
data() {
return {
classObject: ["static", "active", { "text-danger": true }],
}
},
}
以上兩種方法,瀏覽器渲染均為
<div class="static active text-danger"></div>
使用三元表達式來切換列表中的 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 : ''
中,因為isActive
是假,表達式的值為第三個,為空值,當isActive
為真時,表達式的值為第二個,即為activeClass
。
??style(內聯樣式)
動態綁定style屬性說明:
- 如果使用動態綁定屬性方法綁定行內樣式,那么style屬性值將不再是字符串,而是表達式,
- 動態綁定style的值既然是表達式,那么就可以在表達式中使用對象.
- 如果值為對象,那么對象的屬性名則為CSS樣式屬性, 值為樣式的值。
- 注意,此時對象中的屬性值,可以是確定的樣式值,也可以是vue的數據變量,
- 因此有些值不能再像
style
標簽中一樣書寫,例如50px
,以前使用不加引號,現在必須加引號
對象寫法關于值的問題
如果使用動態綁定屬性style里的對象值不加引號, 就會有如下的問題:
<h2 :style="{color:red,font-size:30px}">Hello World</h2>
上面的這種寫法就會報錯,?red
和30px
會被當做變量去Vue data
屬性中找對應的數據, 但是找不到就報錯
正確的寫法應該是這樣的
<h2 :style="{color:'red',fontSize:'30px'}">Hello World</h2>
也能正確顯示結果, 但是要注意字符串嵌套問題

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