데이터 바인딩과 템플릿 구문
Vue에서 가장 기본적인 데이터 출력 방식은 중괄호 두 개({{ }})를 사용하는 문자열 보간법이다. 이 방식은 데이터 속성의 값을 실시간으로 화면에 반영한다.
<div id="app">
<p>{{ title }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
title: 'Welcome to Vue'
}
});
</script>
v-html: HTML 렌더링
v-html는 문자열 내의 HTML 태그를 실제 DOM 요소로 해석하여 삽입한다. 보안상 위험할 수 있으므로, 신뢰할 수 있는 콘텐츠에만 사용해야 한다.
<p v-html="rawContent"></p>
<script>
new Vue({
el: '#app',
data: {
rawContent: '<span style="color:red;">Red Text</span>'
}
});
</script>
v-bind: 속성 동적 바인딩
HTML 요소의 속성에 Vue 데이터를 연결할 때 v-bind:를 사용하며, 줄여서 :로 표현할 수 있다.
<a :href="url" :target="isBlank ? '_blank' : '_self'">링크</a>
<script>
new Vue({
el: '#app',
data: {
url: 'https://example.com',
isBlank: true
}
});
</script>
v-if 와 v-show: 조건부 렌더링
v-if는 조건에 따라 요소를 생성하거나 제거하며, v-show는 CSS display 속성을 토글하여 표시 여부를 결정한다.
<div v-if="isVisible">조건부 요소 (v-if)</div>
<div v-show="isVisible">조건부 요소 (v-show)</div>
<script>
new Vue({
el: '#app',
data: {
isVisible: true
}
});
</script>
v-if는 조건이 자주 바뀌지 않을 때 적합하고, v-show는 빈번한 전환이 필요할 때 성능상 유리하다.
v-for: 리스트 렌더링
배열이나 객체를 기반으로 반복적인 요소를 생성할 때 사용한다. 키 값은 컴포넌트 반복 시 필수이며, 가독성을 위해 of도 사용 가능하다.
<ul>
<li v-for="(item, index) in userList" :key="index">
{{ index + 1 }}. {{ item.name }}
</li>
</ul>
<script>
new Vue({
el: '#app',
data: {
userList: [
{ name: 'Alice' },
{ name: 'Bob' },
{ name: 'Charlie' }
]
}
});
</script>
v-on: 이벤트 리스닝
DOM 이벤트를 감지하고 메서드를 호출할 때 사용하며, @로 줄일 수 있다. 다양한 이벤트 수정자가 제공된다.
<button @click="increment">+1</button>
<form @submit.prevent="onSubmit">
<input type="text" v-model="inputValue" />
</form>
<script>
new Vue({
el: '#app',
data: {
inputValue: '',
count: 0
},
methods: {
increment() {
this.count++;
},
onSubmit() {
alert('폼 전송!');
}
}
});
</script>
- .prevent: 기본 동작 차단
- .stop: 이벤트 버블링 중단
- .once: 한 번만 실행
- .capture: 캡처링 모드 활성화
- .self: 자기 자신에서 발생한 이벤트만 처리
- .passive: 스크롤 성능 최적화
v-model: 양방향 데이터 바인딩
폼 요소와 데이터를 실시간으로 동기화한다. 입력창, 체크박스, 라디오 버튼 등에 주로 사용된다.
<input v-model="message" placeholder="입력하세요" />
<p>입력값: {{ message }}</p>
<script>
new Vue({
el: '#app',
data: {
message: ''
}
});
</script>
계산된 속성 (computed)
의존하는 데이터가 변경될 때만 다시 계산되며, 캐싱 기능을 통해 반복 연산을 최적화한다.
<div>
<p>원본: {{ text }}</p>
<p>역순: {{ reversedText }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
text: 'Hello'
},
computed: {
reversedText() {
return this.text.split('').reverse().join('');
}
}
});
</script>
감시자 (watch)
특정 데이터의 변화를 감지하고 그에 따라 비동기 작업이나 복잡한 로직을 수행할 때 사용한다.
<div>전체 이름: {{ fullName }}</div>
<script>
new Vue({
el: '#app',
data: {
firstName: 'John',
lastName: 'Doe',
fullName: 'John Doe'
},
watch: {
firstName(newVal) {
this.fullName = newVal + ' ' + this.lastName;
},
lastName(newVal) {
this.fullName = this.firstName + ' ' + newVal;
}
}
});
</script>
일회성 렌더링: v-once
해당 노드와 하위 바인딩을 처음 한 번만 렌더링하고 이후 변경을 무시한다.
<p v-once>이 값은 변하지 않습니다: {{ staticValue }}</p>
반응성 비활성화: Object.freeze()
객체를 동결하면 Vue는 속성 변화를 추적할 수 없으므로 반응형 업데이트가 불가능해진다.
const obj = { value: 'frozen' };
Object.freeze(obj);
new Vue({
el: '#app',
data: obj // 변경 감지되지 않음
});