iT邦幫忙

5

[筆記][Vue.js]打開Vue.js世界的大門(7)-class也飛不出Vue的掌心!

嗨啊!今天台南終於放晴了,那麼好的天氣,就輕鬆打個文章吧XD,內容來說說如何使用Vue.js來操作class屬性。


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,
})

https://ithelp.ithome.com.tw/upload/images/20180825/20106935AsZl5lQajz.jpg
登愣!對的,只要透過單向綁定就可以簡單指定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得到以下結果:
https://ithelp.ithome.com.tw/upload/images/20180825/20106935viMUdvj2A9.jpg
如果不想把所有的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,
})

https://ithelp.ithome.com.tw/upload/images/20180825/20106935zPnXsUvROg.jpg
如上圖,這樣也能得到同樣的結果,不過我們之前的文章中有提到說,單向綁定可以在{{}}內使用表達式,而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,
})

https://ithelp.ithome.com.tw/upload/images/20180825/201069357yB54pxmeF.jpg
以上三個例子的畫面都會是一樣的!只是我們運用前幾篇學到的東西整理了程式碼的內容,接著我們來提用物件來設定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>

如上面的操作,物件必須要有一個keyvalue,所以當我們使用物件設定class的時候,keyclass的名稱,value則是該class的啟用狀態,true為啟用、false關閉,像上面例子把textBold關起來,所以會只剩字體紅色的效果而已。
https://ithelp.ithome.com.tw/upload/images/20180825/20106935jZjjcogDTX.jpg
當然!如果要像陣列一樣,把綁定的物件從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,
})

https://ithelp.ithome.com.tw/upload/images/20180825/20106935RceNXmJLow.jpg
因為上面我把redAlert改指定為falsetextBoldtrue所以他就會只剩下粗體樣式,而且Vue他有動態綁定的特性,所以如果我們直接更改他的值,畫面上的樣式也會跟著變動,如下方也把textBold的值變更為false
https://ithelp.ithome.com.tw/upload/images/20180825/20106935ONOJwxA4GE.jpg

當然,如果要使用計算屬性判斷,也是完全沒有問題!
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,
})

也是輕鬆搞定!因為回傳的物件中redAlerttextBold的狀態都是true,所以警告文字既是紅色也是粗體:
https://ithelp.ithome.com.tw/upload/images/20180825/20106935C0vcadEx6Y.jpg


如上說了很多很多在Vue中可以操作class的方法,不過也不用每個方法都會,只要找個自己用的最順手的方式就好!當然多看過一些操作方式,在寫程式的靈活度就會變得更高!這點也是我需要學習的,也很感謝許多大大的留言也讓我學到很多!說的好像最後一篇一樣XD,還沒哦!這個系列還很長很長的!

最後文章中有講解不清楚或是理解錯誤、沒有提到的地方,還麻煩各位大大留言告訴我,我會再盡快修正,謝謝各位大大的觀看/images/emoticon/emoticon41.gif


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
jack1234552000
iT邦新手 5 級 ‧ 2019-09-03 16:44:50

一開頭看不太懂
為什麼要v-bind:class?
直接用class不就好了嗎?

引進CSS檔案時
就會依照裏頭的規則
渲染整個網頁不是嗎?

神Q超人 iT邦研究生 5 級 ‧ 2019-09-04 21:48:49 檢舉

沒錯哦!所以一開始只是演示使用 v-bind 的實作而已,但是如果用 class 寫死,就失去了給他變數,然後改變變數重新 Render 新 CSS 的功能。

我要留言

立即登入留言