© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
📑
class와 style 바인딩 ~ event 핸들링 class 바인딩 class에 객체 데이터 연결 이름에 - 등의 부호가 들어간다면 따옴표를 써야 함. ex) :class="{ title__small': small }"
이때 띄어쓰기로 두 개 이상의 클래스를 추가할 수 있음. 작성한 객체 데이터를 데이터 부분에서 선언하는 방법임. 만약 반응형 데이터를 활용해야 한다면 computed
키워드로 반응형 데이터를 사용해야 함. class에 배열 데이터 연결 일반 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로 적어주어도 자동으로 변형됨. 따라서 따옴표를 사용하지 않아도 됨. 두 개의 객체 데이터를 바인딩 할 때는 배열을 사용하면 됨. 이때 중복된 데이터가 있다면 나중에 선언된 객체가 우선순위를 가짐. 조건부 렌더링 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 바인딩을 숨길 수 있음.⚠️
v-if
와
v-for
를 함께 쓰는 걸 권장하지 않음. v-if의 우선순위가 더 높기 때문에 for문을 돌돌면서 조건을 만들면 원치 않는 결과를 반환할 수 있음.
[참고] 리스트 렌더링 v-for
로 배열 리스트를 렌더링할 수 있음. 두 번째 인자로 index 제공.v-for를 사용하여 객체의 속성을 반복할 수 있음. 인자로 value, key, index를 제공. 단, index의 순서는 일관적이지 않음. v-for
와 :key=""
속성을 같이 사용해야 함. key는 고유한 속성을 증명함.push 등 배열을 직접적으로 바꾸는 변이 메소드를 사용하면 데이터 변경이 감지됨. filter, slice 등 새로운 배열을 할당해야 하는 메소드 또한 기존 데이터의 값 변형을 만든다면 전부 새로 그리는 것이 아닌 바뀐 데이터만 변경함(Vue의 최적화, computed). 컴포넌트의 v-for 일반적으로 사용하는 v-bind는 한 방향으로 값을 전달하는 단방향 데이터 바인딩 임. 양방향으로 가능하게 하려면 v-model
이란 디렉티브를 사용해야 함. 이벤트 핸들링 @
를 이용한 직접 바인딩. ex) <button @click="counter += 1">Add 1</button>
메소드 호출을 통한 이벤트 핸들링. ex) <button @click="greet">Greet</button>
매개변수를 이용한 이벤트 핸들링. ex) <button @click="say('hi')">Say hi</button>
원본 DOM 이벤트에 액세스 해야할 때 $event
를 사용해 메소드에 전달할 수 있음(순서 무관). 하나의 이벤트에 여러 이벤트를 실행하려면 하나의 이벤트 실행 후 세미콜론 또는 쉼표로 마무리하면 됨(복합 이벤트 핸들러). 이벤트 수식어 Vue에서 제공하는 이벤트 수식어가 있음.
💡
그 외 Vue에서 수식어를 다양하게 제공하고 있음.
[확인하기] <div id="app">
<button @click="toggle">toggle</button>
<h1 :class="isActive? 'active' : ''" class="title">{{msg}}</h1>
</div>
기본 사용법 <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>
<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>
<div id="app">
<h1 :class="[active, title]" class="title" @click="changTitle">
Hello Vue
</h1>
</div>
<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>
<style>
[v-cloak] {
display: none;
}
</style>
<div id="app">
<h1 v-show="isShow" v-cloak>{{ msg }}</h1>
</div>
<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>
(간단한 Todo 만들기) TodoItem이란 컴포넌트 만듦. <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>
<!-- 클릭 이벤트 전파가 중단되었습니다. -->
<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>