DOM元素經常會動態地綁定一些class類名或style樣式,本章將介紹使用v-bind指令來綁定class和style的多種方法。 ...
本篇目錄:
DOM元素經常會動態地綁定一些class類名或style樣式,本章將介紹使用v-bind
指令來綁定class和style的多種方法。
4.1 瞭解v-bind指令
在第2章時,我們已經介紹了指令v-bind
的基本用法以及它的語法糖,它的主要用法是動態更新HTML元素上的屬性。
回顧一下下麵的示例:
1 <div id="app"> 2 <a v-bind:href="url">超鏈接</a> 3 <img v-bind:src="imgUrl"> 4 <!-- 縮寫為 --> 5 <a :href="url">超鏈接</a> 6 <img :src="imgUrl"> 7 </div> 8 9 <script> 10 var app = new Vue({ 11 el: "#app", 12 data: { 13 url: "https://www.geeksss.com", 14 imgUrl: "http://www.geeksss.com/logo.png" 15 } 16 }); 17 </script>
鏈接的href
屬性和圖片的src
屬性都被動態設置了,當數據變化時,就會重新渲染。
在數據綁定中,最常見的兩個需求就是元素的樣式名稱class
和內聯樣式style
的動態綁定。
它們也是HTML的屬性,因此可以使用v-bind
指令,我們只需要用v-bind
計算出表達式最終的字元串就可以。
不過有時候表達式的邏輯較複雜,使用字元串拼接方法較難閱讀和維護,所以Vue.js增強了對class
和style
的綁定。
4.2 綁定class的幾種方式
4.2.1 對象語法
給v-bind:class
設置一個對象,可以動態地切換class
,例如:
1 <div id="app"> 2 <div :class="{ 'active' : isActive }"></div> 3 </div> 4 5 <script> 6 var app = new Vue({ 7 el: "#app", 8 data: { 9 isActive: true 10 } 11 }); 12 </script>
提示:
上面的:class
等同於v-bind:class
,是一個語法糖,如不特殊說明,後面都將使用語法糖寫法,可以回顧第2.3章節。
上面示例中,類名active
依賴於數據isActive
。
當其為true
時,<div>
會擁有類名active
,為false
時則沒有。
所以上例最終渲染完的結果是:
1 <div id="app"> 2 <div class="active"></div> 3 </div>
對象也可以傳入多個屬性,來動態切換class。
另外,:class
可以與普通class共存,例如:
1 <div id="app"> 2 <div class="static" :class="{'active':isActive, 'error':isError}"></div> 3 </div> 4 5 <script> 6 var app = new Vue({ 7 el: "#app", 8 data: { 9 isActive: true, 10 isError: false 11 } 12 }); 13 </script>
:class
內的表達式每項為真時,對應的類名就會載入,上面渲染後的結果為:
1 <div id="app"> 2 <div class="static active"></div> 3 </div>
當數據isActive
或isError
變化時,對應的class
類名也會更新。
比如當isError
為true
時,渲染後的結果為:
1 <div id="app"> 2 <div class="static active error"></div> 3 </div>
當:class
的表達式過長或邏輯複雜時,還可以綁定一個計算屬性。
這是一種很友好和常見的用法,一般當條件多於兩個時,都可以使用data
或computed
。
例如使用計算屬性:
1 <div id="app"> 2 <div :class="classes"></div> 3 </div> 4 5 <script> 6 var app = new Vue({ 7 el: "#app", 8 data: { 9 isActive: true, 10 error: null 11 }, 12 computed: { 13 classes: function() { 14 return { 15 active: this.isActive && !this.error, 16 "text-fail": this.error && this.error.type === "fail" 17 }; 18 } 19 } 20 }); 21 </script>
除了計算屬性,你也可以直接綁定一個Object類型的數據,或者使用類似計算屬性的methods
。
4.2.2 數組語法
當需要應用多個class時,可以使用數組語法,給:class
綁定一個數組,應用一個class列表:
1 <div id="app"> 2 <div :class="[activeCls, errorCls]"></div> 3 </div> 4 5 <script> 6 var app = new Vue({ 7 el: "#app", 8 data: { 9 activeCls: "active", 10 errorCls: "error" 11 } 12 }); 13 </script>
渲染後的結果為:
1 <div id="app"> 2 <div class="active error"></div> 3 </div>
也可以使用三元表達式來根據條件切換class,例如下麵的示例:
1 <div id="app"> 2 <div :class="[isActive ? activeCls : '', errorCls]"></div> 3 </div> 4 5 <script> 6 var app = new Vue({ 7 el: "#app", 8 data: { 9 isActive: true, 10 activeCls: "active", 11 errorCls: "error" 12 } 13 }); 14 </script>
樣式error
會始終應用,當數據isActive
為true
時,樣式active
才會被應用。
class有多個條件時,這樣寫較為繁瑣,可以在數組中使用對象語法:
1 <div id="app"> 2 <div :class="[{'isActive':isActive}, errorCls]"></div> 3 </div> 4 5 <script> 6 var app = new Vue({ 7 el: "#app", 8 data: { 9 isActive: true, 10 errorCls: "error" 11 } 12 }); 13 </script>
當然,與對象語法一樣,也可以使用data
、computed
和methods
三中方法。
以計算屬性為例:
1 <div id="app"> 2 <button :class="classes">按鈕</button> 3 </div> 4 5 <script> 6 var app = new Vue({ 7 el: "#app", 8 data: { 9 size: "large", 10 disabled: true 11 }, 12 computed: { 13 classes: function() { 14 return [ 15 "btn", 16 { 17 ["btn-" + this.size]: this.size !== "", 18 ["btn-disabled"]: this.disabled 19 } 20 ]; 21 } 22 } 23 }); 24 </script>
示例中的樣式btn
會始終應用,當數據size
不為空時,會應用樣式首碼btn-
,後加size
的值。
當數據disabled
為true
時,會應用樣式btn-disabled
。
所以該示例最終渲染的結果為:
1 <div id="app"> 2 <button class="btn btn-large btn-disabled">按鈕</button> 3 </div>
使用計算屬性給元素動態設置類名,在業務中經常用到,尤其是在寫復用組件的時候。
所以在開發過程中,如果表達式較長或邏輯複雜,應該儘可能地優先使用計算屬性。
4.2.3 在組件上使用
提示:
本節內容依賴第7章組件相關的內容,如果你尚未了結過Vue.js的組件,可以先跳過這節,稍後再閱讀。
如果直接在自定義組件上使用class
或:class
,樣式規則會直接應用到這個組件的根元素上。
例如聲明一個簡單的組件:
1 Vue.component("my-component", { 2 template: "<p class='article'>一些文本</p>" 3 });
然後在調用這個組件時,應用上面兩節介紹的對象語法或數組語法給組件綁定class
。
以對象語法為例:
1 <div id="app"> 2 <my-component :class="{'active':isActive}"></my-component> 3 </div> 4 5 <script> 6 var app = new Vue({ 7 el: "#app", 8 data: { 9 isActive: true 10 } 11 }); 12 </script>
最終組件渲染後的結果為:
1 <div id="app"> 2 <p class="article active">一些文本</p> 3 </div>
這種用法僅適用於自定義組件的最外層是一個根元素,否則會無效。
當不滿足這種條件或需要給具體的子元素設置類名時,應當使用組件的props
來傳遞。
這些用法同樣適用於下一節綁定內聯樣式style
的內容。
4.3 綁定內聯樣式
使用v-bind:style
(即:style
)可以給元素綁定內聯樣式。
方法與:class
類似,也有對象語法和數組語法,看起來很像直接在元素上寫CSS:
1 <div id="app"> 2 <div :style="{ 'color':color, 'fontSize':fontSize+'px' }">文本</div> 3 </div> 4 5 <script> 6 var app = new Vue({ 7 el: "#app", 8 data: { 9 color: "red", 10 fontSize: 14 11 } 12 }); 13 </script>
CSS屬性名稱使用駝峰命名(camelCase)和短橫分隔命名(kebab-case)。
渲染後的結果為:
1 <div id="app"> 2 <div style="color: red; font-size: 14px;">文本</div> 3 </div>
大多數情況下,直接寫一長串的樣式不便於閱讀和維護,所以一般寫在data
或computed
里。
以data
為例改寫上面的示例:
1 <div id="app"> 2 <div :style="styles">文本</div> 3 </div> 4 5 <script> 6 var app = new Vue({ 7 el: "#app", 8 data: { 9 styles: { 10 color: "red", 11 fontSize: 14 + "px", 12 } 13 } 14 }); 15 </script>
應用多個樣式對象時,可以使用數組語法:
1 <div :style="[styleA, styleB]">文本</div>
在實際業務中,:style
的數組語法並不常用,因為往往可以寫在一個對象裡面,而較為常用的應當是計算屬性。
另外,使用:style
時,Vue.js會自動給特殊的CSS屬性名增加首碼,比如transform
。