class 바인딩
<div id="app"> <button @click="toggle">toggle</button> <h1 :class="isActive? 'active' : ''" class="title">{{msg}}</h1> </div>
class에 객체 데이터 연결
<div id="app"> <button @click="toggle">toggle</button> <h1 :class="{ active, 'title__small color__pink': small }" class="title">{{msg}}</h1> </div> <script> const App = { data() { return { msg: "hello vue", active: false, small: false, }; }, methods: { toggle() { this.active = !this.active; this.small = !this.small; }, }, }; const vm = Vue.createApp(App).mount("#app"); </script>
- 객체를 이용하여 표현.
- 객체 이름과 메소드가 같으면 생략 가능함.
- 이름에 - 등의 부호가 들어간다면 따옴표를 써야 함. ex)
:class="{ title__small': small }"
- 이때 띄어쓰기로 두 개 이상의 클래스를 추가할 수 있음.
<div id="app"> <button @click="toggle">toggle</button> <h1 :class="classObject" class="title">{{msg}}</h1> </div> <script> const App = { data() { return { msg: "hello vue", active: false, small: false, }; }, computed: { classObject() { return { active: this.active, small: this.small, }; }, }, methods: { toggle() { this.active = !this.active; this.small = !this.small; }, }, }; const vm = Vue.createApp(App).mount("#app"); </script>
- 작성한 객체 데이터를 데이터 부분에서 선언하는 방법임.
- 만약 반응형 데이터를 활용해야 한다면
computed
키워드로 반응형 데이터를 사용해야 함.
class에 배열 데이터 연결
<div id="app"> <h1 :class="[active, title]" class="title" @click="changTitle"> Hello Vue </h1> </div>
- 일반 class일 경우
['active', 'title']
과 같이 사용함.
- 위의 예시는 반응형 데이터를 이용할 경우임.
style 바인딩
inline style에 데이터 연결
- 기존 class 데이터 연결과 동작 방식이 동일함.
ex)
<h1 :style="{ color, width }" @click="toBlue">Hello Vue</h1>
- 인라인 형식의 click 이벤트 내 여러 메소드를 넣고 싶다면
@click="toBlue(); increaseWidth()"
로 직접 실행해주면 됨.
- dash case인 CSS를 camel case로 적어주어도 자동으로 변형됨. 따라서 따옴표를 사용하지 않아도 됨.
- 두 개의 객체 데이터를 바인딩 할 때는 배열을 사용하면 됨. 이때 중복된 데이터가 있다면 나중에 선언된 객체가 우선순위를 가짐.
조건부 렌더링
<div id="app"> <h1 v-if="isShow">Hello Vue</h1> <template v-else-if="true"> <h2>Apple</h2> <h2>okay</h2> <span>doky</span> </template> <h2 v-else>Good item</h2> </div> <script> const App = { data() { return { isShow: true, }; }, }; const vm = Vue.createApp(App).mount("#app"); </script>
- 조건부끼린 형제요소로 인접해 있어야 함.
- template 태그를 이용해 여러 요소를 한 번에 조건으로 삼을 수 있음. template 태그는
v-if
또는v-for
디렉티브가 있을 때 해당하는 요소를 렌더링하지 않음.
v-show
v-if
대신v-show
를 사용할 수 있음. v-show는 display 속성에 none으로 바꿔 요소를 화면에 보여지거나 안보이게 만듦.
- v-if는 주석처리 시키는 것임(요소 구소 자체를 사라지게 함, lazy, 초기 렌더링 비용 낮으나 전환 비용이 높음).
- 따라서 토글을 자주할 것 같으면 v-show를 권장하나 일반적으로 v-if를 사용함.
- 주의할 점은 이중 괄호를 이용해 데이터를 출력할 때, 데이터 전송이 느리다면 이중 괄호가 그대로 노출될 수 있음. 따라서
v-show
는v-cloak
디렉티브와 함께 사용하는 것이 좋음.
v-cloak
은 출력할 데이터가 준비되기 전까지 보여줄 스타일을 결정함(독립적으로 사용 가능). 해당 스타일에 display 값을 none으로 지정하면 컴파일 되지않은 mustache 바인딩을 숨길 수 있음.
<style> [v-cloak] { display: none; } </style> <div id="app"> <h1 v-show="isShow" v-cloak>{{ msg }}</h1> </div>
리스트 렌더링
v-for
로 배열 리스트를 렌더링할 수 있음. 두 번째 인자로 index 제공.

- v-for를 사용하여 객체의 속성을 반복할 수 있음. 인자로 value, key, index를 제공. 단, index의 순서는 일관적이지 않음.

v-for
와:key=""
속성을 같이 사용해야 함. key는 고유한 속성을 증명함.
- push 등 배열을 직접적으로 바꾸는 변이 메소드를 사용하면 데이터 변경이 감지됨.
- filter, slice 등 새로운 배열을 할당해야 하는 메소드 또한 기존 데이터의 값 변형을 만든다면 전부 새로 그리는 것이 아닌 바뀐 데이터만 변경함(Vue의 최적화, computed).
- v-for의 정수를 넣으면 1부터 시작함.
컴포넌트의 v-for
- 일반적으로 사용하는 v-bind는 한 방향으로 값을 전달하는 단방향 데이터 바인딩임.
- 양방향으로 가능하게 하려면
v-model
이란 디렉티브를 사용해야 함.
<div id="app"> <form @submit="addNewTodo"> <label for="new-todo">Add a todo</label> <input type="text" id="new-todo" placeholder="feed the cat" v-model="newTodoText" /> <button>Add</button> </form> <ul> <todo-item v-for="todo in todos" :key="todo.id" :todo="todo" @remove="removeTodo" /> </ul> </div> <script> const TodoItem = { //emit으로 커스텀 이벤트를 만들 수 있음. template: ` <li> {{ todo.title }} <button @click="$emit('remove', todo.id)">Remove</button> </li>`, //활용할 데이터를 선언 props: ["todo"], }; const App = { components: { TodoItem, }, data() { return { newTodoText: "", todos: [], }; }, methods: { addNewTodo(event) { event.preventDefault(); this.todos.push({ id: Date.now(), title: this.newTodoText, }); this.newTodoText = ""; }, removeTodo(todoId) { this.todos = this.todos.filter((todo) => { return todo.id !== todoId; }); }, }, }; const vm = Vue.createApp(App).mount("#app"); </script>
이벤트 핸들링
@
를 이용한 직접 바인딩. ex)<button @click="counter += 1">Add 1</button>
- 메소드 호출을 통한 이벤트 핸들링. ex)
<button @click="greet">Greet</button>
- 매개변수를 이용한 이벤트 핸들링. ex)
<button @click="say('hi')">Say hi</button>
- 원본 DOM 이벤트에 액세스 해야할 때
$event
를 사용해 메소드에 전달할 수 있음(순서 무관).
<div id="app"> <h1 @click="say('hi', $event)">{{msg}}</h1> </div> <script> const App = { data() { return { msg: "Vue", }; }, methods: { say(message, event) { console.log(message, event); }, }, }; const vm = Vue.createApp(App).mount("#app"); </script>
- 하나의 이벤트에 여러 이벤트를 실행하려면 하나의 이벤트 실행 후 세미콜론 또는 쉼표로 마무리하면 됨(복합 이벤트 핸들러).
이벤트 수식어
Vue에서 제공하는 이벤트 수식어가 있음.
.self
.once
.passive
.stop
.prevent
.capture
<!-- 클릭 이벤트 전파가 중단되었습니다. --> <a @click.stop="doThis"></a> <!-- 제출 이벤트가 페이지를 다시 로드하지 않습니다. --> <form @submit.prevent="onSubmit"></form> <!-- 수정자는 체이닝이 가능합니다. --> <a @click.stop.prevent="doThat"></a> <!-- 단순히 수식어만 사용이 가능합니다. --> <form @submit.prevent></form> <!-- 캡처 모드를 사용할 때 이벤트 리스너를 사용 가능합니다.--> <!--즉, 내부 엘리먼트를 대상으로 하는 이벤트가 해당 엘리먼트에서 처리되기 전에 여기서 처리합니다. --> <div @click.capture="doThis">...</div> <!-- event.target이 엘리먼트 자체인 경우에만 트리거를 처리합니다.--> <!-- 자식 엘리먼트에서는 처리되지 않습니다.--> <div @click.self="doThat">...</div>
그 외 Vue에서 수식어를 다양하게 제공하고 있음. [확인하기]