1. 조건부 렌더링
1) v-if, v-else-if, v-else
: 해당 블록을 조건부로 렌더링하는 데 사용
<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no 😢</h1>
- v-else는 v-else-if나 v-if 다음 블록에 와야 인식이 된다.
✅ template
- template는 요소들을 래핑해주는 역할로 template 자체는 dom에 보이지 않는다.
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
- v-if가 ok면 내부 요소만 렌더링 된다.
2) v-show
- 요소를 조건부로 표시하는 다른 옵션
<h1 v-show="ok">Hello!</h1>
📌 v-show와 v-if 비교
v-show는 요소가 항상 렌더링 되고, dom에 남아있다. 👉 초기렌더링 비용 ↑, 화면 전환 비용 ↓
v-if 문은 조건이 만족하지 않을 경우 요소가 렌더링 되지 않는다. 👉 초기렌더링 비용 ↓ , 화면 전환 비용 ↑ (lazy하다)
* v-show는 v-cloak 옵션과 같이 사용하는 것이 좋다.(예시) 초기 렌더링 시 숨겨야 할 때
v-cloak : 연결된 컴포넌트 인스턴스가 컴파일을 완료할 때 까지 요소에 남아있다.
<style>
[v-cloak] {
display: none;
}
</style>
<div id="app">
<h1 v-show="isShow" v-cloak>Hello Vue!</h1>
</div>
✅ v-if와 v-for 함 사용하기
<ul>
<template v-for="user in users" :key="user.id">
<li v-if="user.isActive">
{{ user.name }}
</li>
</template>
</ul>
- li에 v-for을 작성하지 않고 template를 이용하여 요소가 생성되는 걸 막는다.
* v-if가 v-for보다 우선순위가 높기 때문에 for의 값을 참조할 때 오류가 생김(computed로 해결은 가능)
2. 리스트 렌더링
1) v-for
: 배열을 기반으로 항목 목록을 렌더링 할 수 있다.
data() {
return {
items: [{ message: 'Foo' }, { message: 'Bar' }]
}
}
<li v-for="item in items">
{{ item.message }}
</li>
* 두번 째 인자를 넣어 인덱스도 참조 가능하다. (item, idx)
✅ 객체
<li v-for="(value, key, index) in myObject">
{{ index }}. {{ key }}: {{ value }}
</li>
✅ 숫자
<span v-for="n in 10">{{ n }}</span>
- 1부터 시작함
* key : v-for을 이용해 요소를 여러개 렌더링 할 때는 고유 속성을 부여하는 것이 권장된다.
<template v-for="todo in todos" :key="todo.name">
<li>{{ todo.name }}</li>
</template>
* 배열을 새로운 배열로 할당할 때(filter 이용) vue가 최적화 하기 때문에 효율적임
ex) todoList 추가, 삭제
<body>
<div id="app">
<form @submit="addNewTodo">
<label for="new-todo">Add a todo</label>
<input
v-model="newTodoText"
id="now-todo"
type="text"
placeholder="E.g. Feedt the cat"
/>
<button>Add</button>
</form>
<ul>
<todo-item
v-for="todo in todos"
:key="todo.id"
:todo="todo"
@remove="removeTodo"
/>
</ul>
</div>
<script>
// 단방향이다 :value
function generateId() {
return `${Date.now()}${Math.random()}`;
}
const TodoItem = {
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(e) {
e.preventDefault();
this.todos.push({
id: generateId(),
title: this.newTodoText,
});
this.newTodoText = "";
console.log(this.todos);
},
removeTodo(todoId) {
this.todos = this.todos.filter((todo) => todo.id !== todoId);
},
},
};
const vm = Vue.createApp(App).mount("#app");
</script>
</body>
2. 이벤트 핸들링
1) v-on(@)
: DOM 이벤트를 수신하고 트리거할 수 있음
<button @click="greet">Greet</button>
- 버튼 클릭시, methods 내부에 정의한 greet() 를 실행한다.
* 함수 매개변수 : 순서와 상관없이 $event 가 이벤트를 가져온다.
$을 안붙이면 마지막 매개변수가 event가 된다.
<button @click="say('hello', $event)">Say hello</button>
✅ 여러 함수 할당 : 순서대로 실행된다.
<h1 @click="a(); b(); c();">{{msg}}</h1>
2) 이벤트 수식어
- .stop : event.stopPropagation()
- .prevent : event.preventDefault()
- .self : event.currentTarget(이벤트가 등록된 대상) = event.target(이벤트가 실행된 요소) 일 때
- .capture : 상위 요소부터 이벤트가 내려옴
- .once : 한번만 실행
- .passive : log 랑 화면 렌더링 분리함
<a @click.stop.once="doThis"></a>
3) 키 이벤트
<input @keyup.enter="submit" />
<input type="text" @keyup.alt.exact="log" /> alt만 누를때
- enter를 입력했을 때 submit 실행
- exact를 이용하면 그 키만 눌렀을 때 실행하도록 할 수 있다.
4) 마우스 이벤트
- .left
- .right
- .middle
⚠️ 뷰에서는 이벤트를 바인딩한 요소가 삭제되면 이벤트 리스너도 같이 삭제된다
3. 폼 입력 바인딩
1) :value : 단방향 데이터 바인딩
<h1>{{msg}}</h1>
<input type="text" :value="msg" @input="msg=$event.target.value"/>
- input에 입력한 텍스트를 h1요소와 동기화 하기 위해선(양방향) input 이벤트를 이용해야 한다.
2) v-model : 양방향 데이터 바인딩
<h1>{{msg}}</h1>
<input type="text" v-model="msg" />
✅ checkbox
<input type="checkbox" v-model="checked" />
<input type="checkbox" v-model="checked" checked />
- checked 옵션을 주면 기본으로 체크되어 있다.
- v-model 값을 배열로 설정해 놓으면 checked 된 value값들이 배열로 들어 간다.
✅ radio
<input v-model="picked" type="radio" value="Leon" />
<input v-model="picked" type="radio" value="euna" />
<input v-model="picked" type="radio" value="able" />
data() {
return {
picked: "",
};
},
watch: {
picked(newValue) {
console.log(newValue);
},
},
✅ select
<div>Selected: {{ selected }}</div>
<select v-model="selected">
<option disabled value="">Please select one</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
3) 수식어
ⓐ .lazy : 이벤트 후에 값을 동기화
<input v-model.lazy="msg" />
ⓑ .number : 사용자 입력이 자동으로 숫자로 변경
<input v-model.number="age" />
ⓒ .trim : 공백 제거
<input v-model.trim="msg" />
4. 컴포넌트 기초
1) props 사용
const app = Vue.createApp(App);
app.component("upper-name", {
template: `<div>{{name}}</div>`,
props: ["name"],
},
});
<upper-name name="apple"></upper-name>
<upper-name name="banana"></upper-name>
<upper-name name="cake"></upper-name>
2) 하위 컴포넌트에서 상위 컴포넌트 data 수정
- emit을 이용한다.
<upper-name
v-for="fruit in fruits"
:key="fruit.id"
:name="fruit.name"
@to-upper="toUpper(fruit, $event)"
></upper-name>
const app = Vue.createApp(App);
app.component("upper-name", {
template: `<div @click="capitalize">{{name}}</div>`,
props: ["name"],
methods: {
capitalize() {
this.$emit("to-upper", this.name.toUpperCase());
},
},
});
- emit의 첫번째 인자는 커스텀 이벤트 이름이다.
methods: {
toUpper(fruit, uppername) {
fruit.name = uppername;
},
},
upper-name 클릭시 capitalize를 실행하고,
upper-name 컴포넌트에서 to-upper라는 이벤트를 바인딩하여 toUpperCase()한 걸
상위 컴포넌트의 methods인 toUpper를 실행하여 값이 바뀌게 된다.
'Frontend > 프로그래머스 FE 데브코스' 카테고리의 다른 글
[DAY 37] Vue (5) (2) | 2022.12.14 |
---|---|
[DAY 36] Vue (4) (0) | 2022.12.12 |
[DAY 34] Vue (2) (0) | 2022.12.06 |
[DAY 33] Vue (1) (0) | 2022.11.30 |
[DAY 32] CSS 심화(4) (2) | 2022.11.29 |