---
# System prepended metadata

title: Class and Style Bindings
tags: [Vue3, 前端(frontend)]

---

# Class and Style Bindings

Vue 提供了 `class` 和 `style` 兩種 directives 的方法來連結綁定 class 和樣式。

## Binding HTML Classes
### Object syntax
將一個 object 傳遞給 `:class` (`v-bind:class` 的語法糖) 來動態切換 classes
```jsx=
<div :class="{ active: isActive }"></div>
```
`active` 為 class 名稱，`isActive` 是程式中的 truthy 或 boolean
當 `isActive` 為 true，就會產生
```jsx=
<div class="active"></div>
```

可以使用多組動態 classes 並且和普通的 class 共存
```jsx=
<div
  class="static"
  :class="{ active: isActive, 'text-danger': hasError }"
></div>
```
```javascript=
data() {
  return {
    isActive: true,
    hasError: false
  }
}

```
上述的 html 和 js 就會產生
```jsx=
<div class="static active"></div>
```
`active` 和 `text-danger` 會因為 `isActive` 和 `hasError` 的真值而產生變化
且可以將 object 取出來，不必是 inline 樣式
```jsx=
<div :class="classObject"></div>
```
```javascript=
data() {
  return {
    classObject: {
      active: false,
      'text-danger': true
    }
  }
}
```
這樣結果就會是
```jsx=
<div class="static text-danger"></div>
```

還可以將 object 綁定到 `computed` property
```jsx=
<div :class="classObject"></div>
```
```javascript=
data() {
  return {
    isActive: true,
    error: null
  }
},
computed: {
  classObject() {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'
    }
  }
}
```
如此同樣會產生
```jsx=
<div class="static active"></div>
```

### Array syntax
除了可以是 object，也可以將一組 classes 名稱的 array 傳遞給 `:class`
```jsx=
<div :class="[activeClass, errorClass]"></div>
```
```javascript=
data() {
  return {
    activeClass: 'active',
    errorClass: 'text-danger'
  }
}
```
如此會產生
```jsx=
<div class="active text-danger"></div>
```
如果要條件判別，可以使用三元表示法(ternary expression)
```jsx=
<div :class="[isActive ? activeClass : '', errorClass]"></div>
```
這樣子就會條件判斷是否有 `activeClass`，但是 `errorClass` 則是一定會有

另外還能再 array 中使用 object (避免太過冗長)
```jsx=
<div :class="[{ active: isActive }, errorClass]"></div>
```

### With Components
可以在 custom component 上使用 `class` (限定 single root element)，如果原本在 component 就有設定 class 則會一起保留
例如:
```jsx=
// parent.vue
<div id="app">
  <my-component class="baz boo"></my-component>
</div>
```
```jsx=
// my-component.vue
<template>
  <p class="foo bar">Hi!</p>
</template>
```
會 render 出
```jsx=
<p class="foo bar baz boo">Hi</p>
```
同樣可以使用 binding
```jsx=
<my-component :class="{ active: isActive }"></my-component>
```
如果 `isActive` 為 true，就會生成
```jsx=
<p class="foo bar active">Hi</p>
```
如果 component 有多個 root elements 則需要指定哪些需要 class
```jsx=
// my-component.vue
<template>
  <p :class="$attrs.class">Hi!</p>
  <span>This is a child component</span>
</template>
```

## Binding Inline Styles
透過 `:style` 可以直接指派 inline styles 給元件

### Object Syntax
`:style` 用起來像是純粹的 css，只是給予的值是 JavaScript object。給予的 css property names 必須是 `camelCase` 或是 `kebab-case` (就像 `kebab-case` 使用 `-` 區隔)
```jsx=
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

data() {
  return {
    activeColor: 'red',
    fontSize: 30
  }
}
```
直接綁定一個物件會是一個好主意
```jsx=
<div :style="styleObject"></div>

data() {
  return {
    styleObject: {
      color: 'red',
      fontSize: '13px'
    }
  }
}
```
object syntax 也很常和 computed property 搭配使用

### Array syntax
`:style` 和 array syntax 組合可以指派多個 objects 給同一個元件
```jsx=
<div :style="[baseStyles, overridingStyles]"></div>
```

### Auto-prefixing
Vue 會自動加入 prefixes 給支援的 css properties ([vendor prefixes](https://developer.mozilla.org/en-US/docs/Glossary/Vendor_Prefix))

### Multiple Values
可以指派 array 給同一個 css style property
```jsx=
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
```
瀏覽器會選用在支援的值中選擇最後一個來使用

###### tags:`前端(frontend)`,`Vue3`