Development/Vue.js

[Vue.js] Document 따라하기 - Class and Style Bindings

도롱뇽도롱 2022. 6. 3. 18:00
반응형

데이터 바인딩의 일반적인 요구사항은 element의 클래스 목록과 인라인 스타일을 조작하는 것이다. 클래스와 스타일 모두 속성이므로 v-bind를 이용하여 처리할 수 있다. 표현식으로 최종 문자열을 계산하기만 하면 된다. 하지만 문자열 연결을 방해하는 것은 성가시고 오류가 발생하기 쉽기에 Vue는 v-bind가 class와 style과 함께 사용될 때 특별한 개선 사항을 제공한다. 문자열 외에도 표현식은 객체 또는 배열로 평가될 수 있다.

 

Binding HTML Classes

Binding to Objects

:class(v-bind:class의 약자)에 객체를 전달하여 클래스를 동적으로 전환할 수 있다.

<div :class="{ active: isActive }"></div>

위 구문은 active 클래스의 존재 여부가 isActive의 값(true/false)에 따라 결정됨을 의미한다.

 

객체에 더 많은 필드를 포함하여 여러 클래스를 토글 할 수 있다. 또한 :class 지시문은 일반 class 속성과 공존할 수도 있다. 따라서 다음과 같은 형식을 따르게 된다.

data() {
  return {
    isActive: true,
    hasError: false
  }
}

다음과 같은 템플릿을 작성하면

<div
  class="static"
  :class="{ active: isActive, 'text-danger': hasError }"
></div>

아래와 같이 렌더링 된다.

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

isActive 또는 hasError가 변경되면 그에 따라 클래스 목록이 업데이트된다. 예를 들어 hasError가 true가 된다면 클래스 목록은 "static active text-danger"가 된다.

Binding to Objects
Binding to Objects

바인딩된 객체는 인라인일 필요 없다.

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

Binding to Object Not Inline
Binding to Objects Not Inline

이것은 동일한 결과를 렌더링한다. 객체를 반환화는 computed 속성에 바인딩할 수도 있으며, 이는 일반적이고 강력한 패턴이다.

data() {
  return {
    isActive: true,
    error: null
  }
},
computed: {
  classObject() {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'
    }
  }
}
<div :class="classObject"></div>

Binding to Objects using Computed
Binding to Objects using computed

 

Binding to Arrays

:class를 배열에 바인딩하여 클래스 목록을 적용할 수 있다.

data() {
  return {
    activeClass: 'active',
    errorClass: 'text-danger'
  }
}
<div :class="[activeClass, errorClass]"></div>

아래와 같이 렌더링된다.

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

Binding to Arrays
Binding to Arrays

삼항 표현식을 사용하여 목록 내 클래스도 토글 할 수 있다.

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

위와 같이 작성 시, errorClass는 항상 적용되지만 activeClass는 isActive의 값이 true일 때만 적용된다.

Binding to Arrays with Ternary Expressions
Binding to Arrays with Ternary Expressions

그러나 조건부 클래스가 여러 개인 경우 다소 장황할 수 있기 때문에 배열 구문 내에서 객체 구문을 사용할 수도 있다.

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

Binding to Arrays with Object Syntax
Binding to Arrays with Object Syntax

 

With Components

이 섹션에서는 Components에 대한 사전 지식이 있다고 가정한다. 만약 Components에 대한 지식이 없다면 건너뛰고 나중에 읽어볼 것을 권장한다.

 

root element가 하나로 구성된 component에서 class 속성을 사용하면 해당 클래스가 component의 root element에 이미 정의된 기존 클래스와 병합된다.

 

my-component라는 component의 템플릿이 아래와 같다고 가정하고

<!-- child component 템플릿 -->
<p class="foo bar">Hi!</p>

사용할 때 몇 가지 클래스를 추가한다면

<!-- component를 사용할 때 -->
<my-component class="baz boo"></my-component>

렌더링 된 HTML은 다음과 같다.

<p class="foo bar baz boo">Hi</p>

With Components
With Components

클래스 바인딩도 마찬가지다.

<my-component :class="{ active: isActive }"></my-component>

isActive가 true라면 렌더링된 HTML은 다음과 같다.

<p class="foo bar active">Hi</p>

With Components using class bindings
With Components using class bindings

여러 개의 root element로 component가 구성되어 있는 경우, 클래스를 적용할 element를 정의해야 한다. $attr component 속성을 사용하여 이 작업을 수행할 수 있다.

<!-- my-component 템플릿에서 $attrs 속성 사용 -->
<p :class="$attrs.class">Hi!</p>
<span>This is a child component</span>
<my-component class="baz"></my-component>

아래와 같이 렌더링 된다.

<p class="baz">Hi!</p>
<span>This is a child component</span>

With Components with multiple roots
With Components with multiple roots

Component 속성 상속에 대한 자세한 내용은 추후 Fallthrough attributes 섹션에서 확인할 수 있다.

 

Binding Inline Styles

Binding to Objects

:style은 HTML element의 style 속성에 해당하는 JavaScript 객체에 대한 바인딩을 지원한다.

data() {
  return {
    activeColor: 'red',
    fontSize: 30
  }
}
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

Binding Inline Styles - Binding to Objects
Binding Inline Styles - Binding to Objects

camelCase가 권장되지만 :style은 kebab-cased(실제 css에서 사용되는 방식)도 지원한다. 예를 들면 아래와 같다.

<div :style="{ 'font-size': fontSize + 'px' }"></div>

템플릿이 더 깔끔해지도록 style 객체에 직접 바인딩하는 것이 좋다.

Binding Inline Styles - Binding to Objects Advanced
Binding Inline Styles - Binding to Objects Advanced

일반적으로 객체를 이용한 스타일 바인딩은 종종 객체를 반환하는 computed 속성과 함께 사용된다.

 

Binding to Arrays

여러 스타일 객체로 구성된 배열을 :style에 바인딩할 수 있다.

<div :style="[baseStyles, overridingStyles]"></div>

Binding Inline Styles - Binding to Arrays
Binding Inline Styles - Binding to Arrays

 

Auto-prefixing

Vue는 런타임에 현재 브라우저에서 지원되는 스타일 속성을 확인하여 브라우저가 특정 속성을 지원하지 않으면 해당 속성과 다양한 벤더 접두사가 붙은 변형을 테스트하여 지원되는 속성을 찾아 추가한다.

 

Multiple Values

스타일 속성에 여러 값의 배열을 제공할 수 있다.

<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>

이 경우에는 브라우저가 지원하는 배열의 마지막 값만 렌더링 한다. 위의 예에서 접두사가 붙지 않는 flexbox를 지원하는 브라우저에 대해 display:flex를 렌더링하며, 만약 브라우저가 -webkit-box와 -ms-flexbox를 동시에 지원한다고 가정한다면 display:-ms-flexbox를 렌더링한다.

Binding Inline Styles - Multiple Values
Binding Inline Styles - Multiple Values

 

관련 Repo

https://github.com/galaxyuliana/VueExercises/tree/master/first-vue-project/src/components/Exercise/04

 

참고자료

https://vuejs.org/guide/essentials/class-and-style.html

반응형