嗨啊!今天台南終於放晴了,那麼好的天氣,就輕鬆打個文章吧XD,內容來說說如何使用Vue.js來操作class
屬性。
v-bind
綁定class
的資料就好?沒錯!如果能夠這麼想就可以上一頁繼續看下一篇...欸欸!不是啦XD,不一樣!真的!相信我真的和你想像中的不同!不過既然有這個想法,我們可以先實做用v-bind
綁定class
的值!
HTML
<div id="messageVue">
<span :class="messageClass">{{message}}</span>
</div>
這次別忘了還有CSS
CSS
/*把字變成紅色*/
.redAlert{
color:red;
}
JavaScript
let messageData = {
message : '這裡是警告!',
messageClass : 'redAlert',
}
let messageVue = new Vue({
el:'#messageVue',
data:messageData,
})
登愣!對的,只要透過單向綁定就可以簡單指定class
了!但是在實務上class
通常都不會只有一個而已,對吧!當我們需要同時設定多個class
該怎麼做呢?有兩個方法,第一個是用陣列、第二個是物件。
class
使用陣列填入多個class
的值,並透過v-bind
把值都綁定到class
上面,所以下方在CSS
內增加一個textBold
樣式,以下範例的CSS
就用這兩種樣式,不會再改變了。
HTML
<div id="messageVue">
<!--直接指定CSS中的class名稱-->
<span :class="['redAlert','textBold']">{{message}}</span>
</div>
CSS
.redAlert{
color:red;
}
/*把字體變成租體*/
.textBold{
font-weight:bold;
}
或是也可以將所有要綁定的class
存在messageData
中,所以以下把原本messageClass
的值改為一個陣列,HTML
的:class
則是直接指定messageClass
。
HTML
<div id="messageVue">
<!--直接指定CSS中的class名稱-->
<span :class="messageClass">{{message}}</span>
</div>
JavaScript
let messageData = {
message : '這裡是警告!',
messageClass : ['redAlert','textBold'],
}
let messageVue = new Vue({
el:'#messageVue',
data:messageData,
})
上述兩個例子,都能夠成功綁定多個class
得到以下結果:
如果不想把所有的class
都丟到一個陣列管理的話,在messageData
內把每個class
拆成各自的屬姓,並把陣列移到前方v-bind
綁定的值,如下:
HTML
<div id="messageVue">
<!--在這裡改成陣列-->
<span :class="[textRed,textBold]">{{message}}</span>
</div>
JavaScript
let messageData = {
message : '這裡是警告!',
//這裡把原本的messageClass陣列拆開成兩個屬性
textRed : 'redAlert',
textBold : 'textBold',
}
let messageVue = new Vue({
el:'#messageVue',
data:messageData,
})
如上圖,這樣也能得到同樣的結果,不過我們之前的文章中有提到說,單向綁定可以在{{}}
內使用表達式,而class
的陣列內也一樣做的到,我們直接修改HTML
!
<div id="messageVue">
<!--把陣列的第一個索引值變成一串表達式-->
<span :class="[false ? textRed : '',textBold]">{{message}}</span>
</div>
透過這個表達式false ? textRed : ''
,就可以去控制目前是否要加入這個class
,如果他的條件不成立就能讓class
指定到空值或是另一個class
上,上方的例子我直接用false
判斷,所以他綁定後的結果就不會有textRed
了,而因為上方只操作第一個索引,所以textBold
不會受影響!
不過像上方的例子textBold
如果是常態必須要指定的class
,不需要把他寫進JavaScript
的話,也可以另外指定class="textBold"
,他和:class
之間是不會互相影響的!所以下面的寫法,結果也會和上方一樣:
HTML
<div id="messageVue">
<!--把textBold獨立出來寫-->
<span class="textBold" :class="[false?textRed:'']">{{message}}</span>
</div>
JavaScript
let messageData = {
message : '這裡是警告!',
//JS就不需要再另外指定textBold的屬性了
textRed : 'redAlert',
}
let messageVue = new Vue({
el:'#messageVue',
data:messageData,
})
這時候我們又會想「奇怪?之前是不是也有類似的情形?」,沒錯!如果我們把表達式寫在後面處理,會不會更好?所以現在這個情況最適合的屬性就是computed
!計算屬性!把他加進去:
HTML
<div id="messageVue">
<!--把陣列的第一個索引值改成計算屬性-->
<span class="textBold" :class="[textAlert]">{{message}}</span>
</div>
JavaScript
let messageData = {
message : '這裡是警告!',
textRed : 'redAlert',
}
//計算屬性
let messageComputed = {
//控制是否回傳textRed的值,否就回傳空
textAlert : () => {
return false ? messageData.textRed : ''
}
}
let messageVue = new Vue({
el:'#messageVue',
data:messageData,
computed:messageComputed,
})
以上三個例子的畫面都會是一樣的!只是我們運用前幾篇學到的東西整理了程式碼的內容,接著我們來提用物件來設定class
,用法其實差不多!如果理解上面的操作,那下面的也絕對不困難!
class
物件和陣列最大的差別應該就是key
了,但是PHP
的陣列似乎也有key
...好的!我們先把焦點放在JavaScript
,陣列裡面是用索引代表每個值的位置,而物件則是擁有一個key
對一個value
的特性,所以如果使用物件來設定多個class
也必須遵守這個規則,那是什麼意思呢?看一下範例吧!
HTML
<div id="messageVue">
<!--把CSS中的class名稱設為key,對應的value值為啟用狀態-->
<span :class="{'redAlert':true,'textBold':false}">{{message}}</span>
</div>
如上面的操作,物件必須要有一個key
及value
,所以當我們使用物件設定class
的時候,key
是class
的名稱,value
則是該class
的啟用狀態,true
為啟用、false
關閉,像上面例子把textBold
關起來,所以會只剩字體紅色的效果而已。
當然!如果要像陣列一樣,把綁定的物件從HTML
中改放到messageData
也可以:
HTML
<div id="messageVue">
<!--重新綁定為messageClass-->
<span :class="messageClass">{{message}}</span>
</div>
JavaScript
let messageData = {
message : '這裡是警告!',
//把要綁定的class內容存在這裡
messageClass : {
//這裡可以的class名稱可以不用是字串
redAlert:false,
textBold:true,
}
}
//先把計算屬性拿掉
let messageVue = new Vue({
el:'#messageVue',
data:messageData,
})
因為上面我把redAlert
改指定為false
,textBold
為true
所以他就會只剩下粗體樣式,而且Vue他有動態綁定的特性,所以如果我們直接更改他的值,畫面上的樣式也會跟著變動,如下方也把textBold
的值變更為false
:
當然,如果要使用計算屬性判斷,也是完全沒有問題!
HTML
<div id="messageVue">
<!--改成綁定計算屬性的textAlert-->
<span :class="textAlert">{{message}}</span>
</div>
JavaScript
let messageData = {
message : '這裡是警告!'
}
//計算屬性
let messageComputed = {
//這個屬性會回傳要加入class的物件
textAlert : () =>{
//宣告一個要回傳的物件
let classObj = {}
//設定class樣式名稱和他們的值
classObj.redAlert = true
classObj.textBold = true
//回傳物件內容
return classObj
}
}
let messageVue = new Vue({
el:'#messageVue',
data:messageData,
computed:messageComputed,
})
也是輕鬆搞定!因為回傳的物件中redAlert
即textBold
的狀態都是true
,所以警告文字既是紅色也是粗體:
如上說了很多很多在Vue中可以操作class
的方法,不過也不用每個方法都會,只要找個自己用的最順手的方式就好!當然多看過一些操作方式,在寫程式的靈活度就會變得更高!這點也是我需要學習的,也很感謝許多大大的留言也讓我學到很多!說的好像最後一篇一樣XD,還沒哦!這個系列還很長很長的!
最後文章中有講解不清楚或是理解錯誤、沒有提到的地方,還麻煩各位大大留言告訴我,我會再盡快修正,謝謝各位大大的觀看
一開頭看不太懂
為什麼要v-bind:class?
直接用class不就好了嗎?
引進CSS檔案時
就會依照裏頭的規則
渲染整個網頁不是嗎?
沒錯哦!所以一開始只是演示使用 v-bind
的實作而已,但是如果用 class
寫死,就失去了給他變數,然後改變變數重新 Render 新 CSS 的功能。