본 글은 Vue.js 공식문서의 클래스와 스타일 바인딩을 제가 알아보기 쉽게 풀어쓴 글 입니다.
데이터 바인딩은 일반적으로 엘리먼트의 클래스 목록과 인라인 스타일을 조작하기 위해 사용됩니다.
클래스를 동적으로 토글하기 위해 v-bind:class
에 객체를 전달할 수 있습니다.
<div v-bind:class="{ active: isActive }"></div>
이 구문에서 동적으로 토글한다는 말의 의미는 active
라는 클래스를 동적으로 적용할 수 있다는 의미입니다. isActive
값이 true이면 active
클래스가 적용되고, false면 적용되지 않습니다.
객체에 필드가 더 있으면 여러 클래스를 토글할 수 있습니다. 또한 v-bind:class
디렉티브는 일반 클래스 속성과 공존할 수 있습니다.
html이 아래와 같고,
# html
<div
class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }"
></div>
데이터가 아래와 같을 때,
# js
data: {
isActive: true,
hasError: false
}
아래와 같이 렌더링 됩니다. 미리 지정되어있던 static
과 true 값을 받은 active
클래스가 적용되었습니다. 반대로 isActive
가 false이고, hasError
값이 true 일 경우 active
가 사라지고, text-danger
가 나타나게 됩니다.
# html
<div class="static active"></div>
바인딩 객체는 인라인 일 필요는 없습니다.(인라인에 적어주지 않아도 됩니다.)
# html
<!-- 렌더링 결과 -->
<div v-bind:class="classObject"></div>
# js
data: {
classObject: {
active: true,
'text-danger': false
}
}
위와 같이 바인딩 객체로 작성해도 동일하게 렌더링 됩니다.
# html
<!-- 렌더링 결과 -->
<div class="static active"></div>
또한 객체를 반환하는 computed(계산된 속성)에도 바인딩 할 수 있습니다.
# html
<div v-bind:class="classObject"></div>
# js
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
위의 classObject
에는 computed 속성에서 계산된 객체가 담기고, 이 객체가 html에서 바인딩 됩니다.
처음에는 error
가 null
로 제시된 부분이 이해가 안됐는데, 실제 예시라고 가정했을 때 error
에는 실제 에러 값이 들어갈거고, 이 에러 값의 type
이 fatal
일 때 true로 적용되어 text-danger
클래스가 적용된다는 말이었습니다.
배열을 사용하여 클래스 목록을 지정할 수도 있습니다.
#html
<div v-bind:class="[activeClass, errorClass]"></div>
#js
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
위 구문의 렌더링 결과는 아래와 같습니다. 인라인에 있는 배열의 값에 해당하는 data 값이 적용되어 클래스 목록이 지정되었습니다.
# html
<div class="active text-danger"></div>
삼항 연산자를 이용해서 조건부 토글도 할 수 있습니다. 아래의 구문에서는 isActive
가 true 일 때만 activeClass
를 적용합니다.
# html
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
하지만 여러 조건부 클래스가 있는 경우 복잡해질 수 있습니다. 이런 경우에는 배열 구문 내에서 객체 구문을 사용해 해결할 수 있습니다. 위의 객체 구문에서 살펴봤듯이 isActive
의 조건에 따라 클래스 목록이 정의됩니다.
# html
<div v-bind:class="[{ active: isActive }, errorClass]"></div>
사용자 정의 컴포넌트로 클래스 속성을 사용하면, 클래스가 컴포넌트의 루트 엘리먼트에 추가됩니다. 이 엘리먼트는 기존 클래스는 덮어쓰지 않습니다.
예를 들어 아래와 같이 컴포넌트를 선언한 후,
# js
Vue.component('my-component', {
template: '<p class="foo bar">Hi</p>'
})
HTML에서 컴포넌트를 사용할 때 클래스를 일부 추가해봅니다.
# html
<my-component class="baz boo"></my-component>
이 경우 아래와 같이 HTML이 렌더링 됩니다. 선언 시 적용된 클래스와 사용할 때 추가된 클래스가 모두 목록에 담겨 적용되었습니다.
# html
<p class="foo bar baz boo">Hi</p>
클래스 바인딩에도 동일하게 이 방식이 적용됩니다.
# html
<my-component v-bind:class="{ active: isActive }"></my-component>
isActive
가 참일 경우 렌더링된 HTML은 다음과 같습니다.
# html
<p class="foo bar active">Hi</p>
컴포넌트를 사용할 때 작성한 active
도 클래스로 적용되었습니다.
v-bind:style
객체 구문은 거의 CSS 처럼 보이지만 Javascript 객체 입니다. 속성 이름에는 camelCase와 kebab-case를 사용할 수 있습니다.
camelCase : 이어지는 단어는 대문자로 시작
kebab-case: '-'로 단어 연결
# html
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
# js
data: {
activeColor: 'red',
fontSize: 30
}
스타일 객체에 직접 바인딩하여 템플릿을 더 간결하게 만들 수도 있습니다.
# html
<div v-bind:style="styleObject"></div>
# js
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
클래스 바인딩과 마찬가지로 객체를 반환하는 computed(계산된 속성)도 적용 가능합니다.