이번 포스트에서는 v-bind로 시작하는 directive에 대해서 살펴보자. 본 내용에 들어가기 전에 directive의 기본 사용법을 다시 한번 상기시켜보자.
v-bind
v-bind?
v-bind는 html의 속성에 model의 데이터를 연결할 때 사용된다. v-bind는 전달인자로 연결하려는 속성을 지정해주면 되고 편의상 v-bind는 생략하고 사용하기도 한다.
v-bind:속성명=사용할값
:속성명=사용할값
간단한 사용 예를 살펴보자. 다음의 코드는 기본형 값을 반응형으로 관리하기 위해서 ref로 label과 linkId를 선언하고 있고 link는 반응형 객체를 사용하기 위해 reactive를 사용하고 있다.
<script>
const { createApp, reactive, ref } = Vue;
createApp({
setup() {
const label = ref("vuejs.org");
const linkId = ref("vue");
const link = reactive({
to: "http://vuejs.org",
title: "뷰 공식 사이트",
});
return { label, linkId, link };
},
}).mount("#app");
</script>
이를 template에서 사용하면 아래와 같다.
<div id="app">
<a v-bind:id="linkId" v-bind:href="link.to" :title="link.title">{{label}}</a>
</div>
이 결과 생성되는 DOM과 화면은 아래와 같다.
다양한 값의 활용
v-bind는 단순한 문자열, 숫자, boolean등 단순 값 뿐 아니라 객체를 바인딩 시킬 수도 있다.
boolean 이 사용되는 경우는 disabled나 editable 처럼 값 없이 속성만 사용되는 경우에 적용이 된다.
객체를 통째로 바인딩하는 경우는 객체의 속성들을 모두 바인딩하는 경우이며 이런 경우에는 v-bind 라고만 쓰고 축약형으로는 사용할 수 없다.
<script>
const { createApp, reactive, ref } = Vue;
createApp({
setup() {
const btnDisabled = ref(true);
const inputAttr = reactive({
type: "number",
value: 4,
id: "age",
});
return { btnDisabled, inputAttr };
},
}).mount("#app");
</script>
위 코드를 template에서 사용해보자.
<div id="app">
<button :disabled="btnDisabled">못 누를껄?</button>
<input v-bind="inputAttr" />
</div>
결과로 생성된 DOM 과 출력결과이다.
value에 v-bind를 하는 경우는 단방향이다. 만약 양방향의 처리를 위해서는 v-model을 사용해야 한다.
동적 속성 바인딩
동적 속성 바인딩은 값이 아니라 속성 이름 자체를 바인딩할 때 사용된다. 이를 위해 []로 전달 인자를 묶어준다.
v-bind:[attributeName] = value
이때 기억해둘 내용은 attributeNamer과 연결되는 속성은 소문자로 변경되서 연결된다는 점이다. 따라서 연결되는 data의 이름은 소문자로 작성되어야 한다. (html에서의 속성 이름은 대소문자를 구별하지 않기 때문이다.)
<body>
<div id="app">
<div v-bind:[ATTRNAME]="attrValue">Hi</div> <!--ATTRNAME이라고 썼지만 결국 attrname이 연결됨-->
</div>
</body>
<script>
const { createApp, ref } = Vue;
createApp({
setup() {
const attrname = ref("id");
const attrValue = ref("custom");
return { attrname, attrValue };
},
}).mount("#app");
</script>
위 상황에서 실제 생성된 DOM 과 화면은 아래와 같다.
만약 attrname을 attrName이라고 사용하는 경우는 제대로 된 속성 연결이 안되기 때문에 아래와 같은 warn이 발생한다.
vue@3:1616 [Vue warn]: Property "attrname" was accessed during render but is not defined on instance. at <App>
css style 적용
v-bind와 css 적용
v-bind가 가장 많이 사용되는 예 중 하나가 css style의 적용이다.
웹 프로그래밍을 하다보면 미리 class 별로 css를 작성해 놓은 후 상황에 따라 동적으로 class를 바꿔가며 css를 적용하는 경우가 많은데 이때 class 속성을 적용하기 위해 v-bind를 사용한다.
예를 들어 아래처럼 set1, set2, set3 클래스에 대한 스타일이 미리 정의해 보자.
<style>
.set1 {
background-color: aqua;
color: purple;
}
.set2 {
text-decoration: overline;
font-style: italic;
}
.set3 {
border: 1px solid blue;
}
</style>
v-bind를 통해서 class를 지정할 때는 문자열이나 배열 형태의 자료를 이용해서 적용할 클래스를 나열할 수 있다.
<script>
const { createApp, ref } = Vue;
createApp({
setup() {
const classList = "set1 set2";
const activeSet1 = true;
const style1 = "set1";
const style2 = "set2";
const style3 = "set3";
return { classList, activeSet1, style1, style2, style3 };
},
}).mount("#app");
</script>
활용하는 모습을 살펴보자.
<div :class="classList" class="set3">단순 value를 이용한 바이딩</div>
<div :class="[style2, style3]">배열을 이용한 바인딩</div>
<div :class="[activeSet1? style1: style2, style3]">조건식을 이용한 바인딩</div>
첫 번째 케이스는 고정된 set3와 함께 classList 내용인 set1, set2가 적용되는 예이다.
두 번째 케이스는 배열을 이용해서 2가지 class를 모두 지정하는 경우이다.
세 번째 케이스는 조건식을 이용하는 경우로 지금은 activeSet1이 true이므로 style1과 style3에 해당하는 set1, set3가 적용된다. 따라서 위 바인딩이 결과는 아래와 같다.
또는 boolean 타입의 값을 갖는 속성으로 구성된 객체를 이용해서 해당 class를 토글 처리할 수도 있다.
<div :class="{set1:activeSet1, set2:true}">객체를 이용한 바인딩</div>