데이터 바인딩은 일반적으로 엘리먼트의 클래스 목록과 인라인 스타일을 조작하기 위해 자주 사용되는데, 이 두 속성은 v-bind를 사용하여 처리할 수 있습니다. v-bind
의 표현식으로 최종 문자열을 계산하지만, 문자열 연결에 직접 간섭하는 것은 오류가 발생하기 쉽기 때문에 Vue는 v-bind
와 함께 class
와 style
을 사용할 수 있는 기능을 제공합니다.
class 바인딩
객체 구문
표현식은 문자열 이외에 객체 또는 배열을 이용할 수 있는데, Vue는 클래스를 동적으로 토글하기 위해 v-bind:class
에 객체를 전달할 수 있습니다.
<div v-bind:class="{ active: isActive }"></div>
위 코드는 active
클래스가 데이터 속성인 isActive
의 boolean
속성에 의해 결정된다는 것을 뜻하는데, 객체에 필드가 여러개 있는 경우에는 여러 클래스를 함께 토글 할 수 있습니다. 또 v-bind:class
는 일반적인 class
속성과도 함께 사용할 수 있습니다.
<div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }" ></div>
data: { isActive: true, hasError: false }
위의 코드와 데이터로 렌더링을 하면 다음과 같이 false
속성인 text-danger
문자열을 제외한 static
, active
클래스를 가지는 엘리먼트가 생성되는 것을 확인할 수 있습니다.
<div class="static active"></div>
바인딩 데이터에서 isActive
또는 hasError
가 변경되면 클래스 목록도 업데이트되는데, 만약 hasError
가 true
가 되면 엘리먼트의 클래스 목록은 “static active text-danger”가 됩니다.
v-bind:class
에 바인딩하는 객체는 꼭 인라인으로 작성할 필요는 없습니다. 다음과 같이 데이터에서 객체를 직접 바인딩해도 같은 엘리먼트가 생성되는 것을 확인할 수 있습니다.
<div v-bind:class="classObject"></div>
data: { classObject: { active: true, 'text-danger': false } }
또한 객체를 반환하는 computed 속성에도 바인딩 할 수 있는데, 이것은 일반적이지만 강력한 패턴입니다.
data: { isActive: true, error: null }, computed: { classObject: function () { return { active: this.isActive && !this.error, 'text-danger': this.error && this.error.type === 'fatal' } } }
배열 구문
v-bind:class
에는 다음과 같이 객체 뿐만 아니라 배열도 전달할 수 있습니다.
<div v-bind:class="[activeClass, errorClass]"></div>
data: { activeClass: 'active', errorClass: 'text-danger' }
v-bind:class에 배열을 전달하는 경우에는 데이터에 boolean 속성의 값이 아닌 실제로 적용될 클래스 이름의 ‘문자열’ 값이 들어갑니다. 위의 코드를 렌더링 하면 다음과 같이 active
와 text-danger
클래스를 가진 엘리먼트가 생성되는 것을 확인할 수 있습니다.
<div class="active text-danger"></div>
삼항연산자 이용하기
만약 목록에 있는 클래스를 조건부로 토글하고 싶다면 ‘삼항 연산자’를 이용하면 됩니다.
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
위 코드는 항상 errorClass
를 적용하지만, isActive
가 true
인 경우에는 activeClass
라는 클래스를 적용하게 됩니다.
만약 여러개의 조건부 클래스를 사용해야 한다면, 다음과 같이 배열 구문 내에서 객체 구문을 사용할 수도 있습니다.
<div v-bind:class="[{ active: isActive }, errorClass]"></div>
이렇게 배열 구문 내에서 객체 구문을 사용하면 표현식이 불필요하게 복잡해지는 것을 방지할 수 있습니다.
컴포넌트에 사용하기
사용자 정의 컴포넌트로 class 속성을 사용하면, 클래스가 컴포넌트의 루트 엘리먼트에 추가되는데, 이 엘리먼트는 기존 클래스는 덮어쓰지 않습니다.
Vue.component('my-component', { template: '<p class="foo bar">Hi</p>' })
<my-component class="baz boo"></my-component>
위의 코드와 같이 컴포넌트를 선언하면, 다음과 같이 렌더링된 HTML 엘리먼트를 확인할 수 있습니다.
<p class="foo bar baz boo">Hi</p>
즉 컴포넌트 역시 일반적인 HTML 엘리먼드에 v-bind:class를 사용하는 것처럼 동일하게 사용할 수 있습니다.
<my-component v-bind:class="{ active: isActive }"></my-component>
isActive가 true일 경우 HTML은 다음과 같이 렌더링됩니다.
<p class="foo bar active">Hi</p>
style 바인딩
객체 구문
Vue에서 CSS Style을 바인딩하는 객체 구문에는 CSS와 거의 동일한 형태의 JavaScript 객체가 사용됩니다. 속성의 이름은 camelCase
의 형태 또는 "kebab-case"
(따옴표 필수) 형태로 사용할 수 있습니다.
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
data: { activeColor: 'red', fontSize: 30 }
또 클래스 바인딩과 동일하게 객체를 직접 바인딩 할 수도 있고, computed 속성과 함께 사용할 수도 있습니다.
<div v-bind:style="styleObject"></div>
data: { styleObject: { color: 'red', fontSize: '13px' } }
배열 구문
CSS Style을 바인딩할 때 배열 구문을 사용하는 경우에는 같은 스타일의 엘리먼트에 여러 개의 스타일 객체를 사용할 수 있습니다.
<div v-bind:style="[baseStyles, overridingStyles]"></div>
자동 접두사
접두사 자동 추가
v-bind:style
에 -webkit-
, -moz-
, -ms-
, -o-
와 같이 브라우저의 벤더 접두사가 필요한 CSS 속성이 사용되는 경우, Vue는 자동으로 해당 접두사를 감지하여 스타일을 적용합니다.
<div style=" -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); -o-transform: rotate(45deg); transform: rotate(45deg); ">TEST</div>
접두사 자동 선택
Vue는 2.3+버전 부터 스타일 속성에 접두사가 있는 여러 값을 배열로 전달할 수 있습니다. 이때 Vue는 브라우저가 지원하는 배열의 값만 렌더링하는데, 다음 코드의 경우 접두사가 붙지않은 flexbox
를 지원하는 브라우저에서는 display: flex
를 렌더링합니다.
<div v-bind:style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>