v-bind 綁定class與style的方法

如果我們需要隨著資料的條件改變 HTML 元素的樣式,在 VUE 裡面該怎麼做?
以下搭配官網範例,筆記如何透過 v-bind(簡寫為 : )綁定資料的條件到 HTML 元素的 class 跟 style 上面。

class 綁定物件

我們可以用 :class (v-bind:class 的縮寫) 以物件的形式包裝資料動態切換 class ,以布林值來決定class名稱是否會被渲染出來,語法如下:

<div :class="{ 樣式名稱: 布林值 }"></div>

以物件的形式包裝資料,以class名稱當 key,以資料的布林值來決定 class 樣式會不會出現。

以下面的範例來說:

const isActive = ref(true)
const hasError = ref(false)
<div
  class="static"
  :class="{ active: isActive, 'text-danger': hasError }"
></div>

渲染的結果如下,因為 hasError 的值為 false,所以 ‘text-danger’ 不會出現。

<div class="static active"></div>

:class="{ active: isActive, 'text-danger': hasError }" 這一段也可以把 {} 置換為 reactive 物件,把class名稱跟布林值放在 reactive 物件中。

const classObject = reactive({
  active: true,
  'text-danger': false
})
<div :class="classObject"></div>

class綁定 reactive 物件後的渲染效果是一樣的。

<div class="active"></div>

多種狀態的 class 綁定

如下有 null-classtrue-classfalse-class 綁定到相同的資料狀態,可以這樣寫:

{'null-class': status === null, 'true-class': status === true, 'false-class': status === false}

完整範例:

<script setup>
import { ref } from 'vue'

const msg = ref('Hello World!')
const status = ref(null)
</script>

<template>
 <h1 :class="{'null-class': status === null, 'true-class': status === true, 'false-class': status === false}">{{ msg }}</h1>

<h2 :class="[status ? 'true-class':'false-class']">goodbye</h2>

</template>
<style>
.null-class {
  /* 根據null的狀態設定樣式 */
  color: yellow;
}

.true-class {
  /* 根據true的狀態設定樣式 */
  color: blue;
}

.false-class {
  /* 根據false的狀態設定樣式 */
  color:red;
}
</style>

class 綁定 computed

我們可以把 class 屬性的初始值包裝成 ref,然後放入 computed 的物件中做觀察個別 ref 布林值的變化,動態的隨 ref 資料狀態改變 class 的屬性值。

const isActive = ref(true)
const error = ref(null)

const classObject = computed(() => ({
  active: isActive.value && !error.value,
  'text-danger': error.value && error.value.type === 'fatal'
}))

把 computed 觀察的物件 v-bind 綁定到 class 上。

<div :class="classObject"></div>

class 綁定 陣列

宣告一個 ref 常數,把樣式名稱放入 ref() 中。

const activeClass = ref('active')
const errorClass = ref('text-danger')

然後 :class 綁定一個陣列,放入值為樣式名稱的ref常數。

<div :class="[activeClass, errorClass]"></div>

渲染出來的結果如下:

<div class="active text-danger"></div>

使用陣列綁定 class ,如果要隨資料動態改變 class 出現與否,則必須使用三元運算子:

<div :class="[isActive ? activeClass : '', errorClass]"></div>

渲染出來的結果如下,activeClass 只有在 isActive 為 true 時會出現,而 errorClass 則一直都會存在。

<p class="activeClass,errorClass">
</p>

如果嫌三元運算子太冗長,也可以把三元運算子包裝成物件放入陣列中,渲染效果跟三元運算子相同。

<div :class="[{ active: isActive }, errorClass]"></div>

style 綁定 物件

宣告 ref 常數,把 style 的屬性值賦予給 ref 常數。

const activeColor = ref('red')
const fontSize = ref(30)

然後 :style綁定物件,key為style屬性名稱,如color 或 fontSize,值為上面宣告的 ref 常數。

<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

屬性名稱可以用小駝峰(camelCase)方式命名,例如 fontSize。
如果是以 kebab-cased 方式命名,要以單引號包住,例如 ‘font-size’。

如果想要更簡潔,可以把 { color: activeColor, fontSize: fontSize + ‘px’ } 放入一個 reactive 物件中。

const styleObject = reactive({
  color: 'red',
  fontSize: '13px'
})
<div :style="styleObject"></div>

style的三元表達式

style 的三元表達式在於屬性值的部分以()包起來,裡面用三元表達式判斷真假值來決定用哪一個屬性值。

<p :style="{'color':(bool == true ? '#000':'#fff')}">

style 綁定陣列

也可以把樣式屬性包裝成物件,放入陣列中綁定到style上。

const styleObject = reactive({
  color: 'red',
  fontSize: '13px'
})
const baseObject = reactive({
  lineHeight: '1.5rem',  
})

參考資料

Leave a Reply

Your email address will not be published. Required fields are marked *