조건부 렌더링
v-if
v-if 디렉티브는 조건부로 블록을 렌더링하는 데 사용된다.
블록은 디렉티브 표현식이 truthy 값을 반환하는 경우에만 렌더링
v-else
v-else 디렉티브를 사용하여 v-if에 대한 "else 블록"을 나타낼 수 있다.
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
A/B/C 아님
</div>
v-if는 디렉티브이므로 단일 엘리먼트에 연결해야 한다.
하지만 둘 이상의 엘리먼트를 전환하려면 <template> 엘리먼트에 v-if를 사용할 수 있다.
<template v-if="ok">
<h1>제목</h1>
<p>단락 1</p>
<p>단락 2</p>
</template>
v-show
v-show가 있는 엘리먼트는 항상 렌더링되고 DOM에 남아 있다. 엘리먼트의 display CSS 속성만 전환.
v-cloak을 같이 사용하는게 좋다. + 속성 선택자를 전역으로 등록시킨다.
(v-cloak: 준비될 때까지 컴파일되지 않은 템플릿을 숨기는 데 사용, [v-cloak] { display: none }과 같은 CSS 규칙과 결합하여, 컴포넌트가 준비될 때까지 템플릿을 숨기는 데 사용
차이점
v-if는 조건이 true인 경우에는 해당요소를 실제로 구조화해서 출력, false인 경우에는 아예 구조적으로 만들지 않는다.
또한 v-if는 게으르므로(lazy), 초기 조건이 false면 아무 작업도 수행하지 않는다. 조건부 블록은 조건이 true가 될 때까지 렌더링되지 않는다.
v-show는 데이터의 참,거짓과 상관 없이 해당요소를 구조적으로 출력한다. CSS 기반으로 전환 되므로, 초기 조건과 관계없이 항상 렌더링 된다.
v-if는 전환 비용이 더 높고, v-show는 초기 렌더링 비용이 더 높다. 따라서 매우 자주 전환해야 하는 경우 v-show를, 실행 중에 조건이 변경되지 않는 경우 v-if를 사용하는 것이 좋다.
리스트 렌더링
v-for
- v-for 디렉티브를 사용하여 배열을 리스트로 렌더링할 수 있다.
- item in items 형식의 문법이 필요하다. 여기서 items는 배열이고, item은 배열 내 반복되는 앨리먼트의 **별칭(alias)**
배열 변경 감지
Vue는 반응형 배열의 변경 메소드가 호출 되는것을 감지
- 수정 메서드 : push(), pop(), shift(), unshift(), splice(), sort(), reverse()
- 배열 교체
수정 메서드는 이름에서 알 수 있듯이 호출된 원래 배열을 수정한다.
이에 비해 수정이 아닌 방법도 있다. filter(), concat() 및 slice()는 원본 배열을 수정하지 않고 항상 새 배열을 반환한다.
// `items`는 값이 있는 배열의 ref라고 가정된 경우입니다.
items.value = items.value.filter((item) => item.message.match(/Foo/))
- 필터링/정렬 결과 표시
필터링되거나 정렬된 배열을 반환하는 계산된 속성을 만들 수 있다.
- v-if와 유사하게 <template> 태그에 v-for를 사용하여 여러 엘리먼트 블록을 렌더링할 수 있다.
- 컴포넌트에 v-for를 직접 사용할 수 있다. (key 사용)
이벤트 핸들링
이벤트 리스닝하기
- v-on 디렉티브는 단축 문법으로 @ 기호를 사용
- DOM 이벤트를 수신하고 트리거될 때, 사전 정의해둔 JavaScript 코드를 실행할 수 있다.
- v-on:click="handler" 또는 @click="handler"
핸들러 값
- 인라인 핸들러: 이벤트가 트리거될 때 실행되는 인라인 JavaScript(네이티브 onclick 속성과 유사).
- 메서드 핸들러: 컴포넌트에 정의된 메서드 이름 또는 메서드를 가리키는 경로.
메서드 핸들러
대부분의 이벤트 핸들러 논리는 복잡, 인라인 핸들러에서는 실현 가능하지 않을 수 있다.
=> v-on은 컴포넌트의 메서드 이름이나 메서드를 가리키는 경로를 실행할 수 있게 구현

인라인 핸들러에서 메서드 호출
메서드 이름을 직접 바인딩하는 대신, 인라인 핸들러에서 메서드를 호출할 수 있다.
인라인 핸들러에서 이벤트 객체 접근
인라인 핸들러에서 네이티브 DOM 이벤트 객체에 접근해야 하는 경우도 있다. 특수한 키워드인 $event를 사용하여 메서드에 전달
<!-- 특수한 키워드인 $event 사용 -->
<button @click="warn('아직 양식을 제출할 수 없습니다.', $event)">
제출하기
</button>
<!-- 인라인 화살표 함수 사용 -->
<button @click="(event) => warn('아직 양식을 제출할 수 없습니다.', event)">
제출하기
</button>
//js
function warn(message, event) {
// 이제 네이티브 이벤트 객체에 접근할 수 있습니다.
if (event) {
event.preventDefault()
}
alert(message)
}
이벤트 수식어
.stop / .prevent / .self / .capture / .once / .passive
<!-- 클릭 이벤트 전파가 중지됩니다. -->
<a @click.stop="doThis"></a>
<!-- submit 이벤트가 더 이상 페이지 리로드하지 않습니다. -->
<form @submit.prevent="onSubmit"></form>
<!-- 수식어를 연결할 수 있습니다. -->
<a @click.stop.prevent="doThat"></a>
<!-- 이벤트에 핸들러 없이 수식어만 사용할 수 있습니다. -->
<form @submit.prevent></form>
<!-- event.target이 엘리먼트 자신일 경우에만 핸들러가 실행됩니다. -->
<!-- 예를 들어 자식 엘리먼트에서 클릭 액션이 있으면 핸들러가 실행되지 않습니다. -->
<div @click.self="doThat">...</div>
<!-- 이벤트 리스너를 추가할 때 캡처 모드 사용 -->
<!-- 내부 엘리먼트에서 클릭 이벤트 핸들러가 실행되기 전에, 여기에서 먼저 핸들러가 실행됩니다. -->
<div @click.capture="doThis">...</div>
<!-- 클릭 이벤트는 단 한 번만 실행됩니다. -->
<a @click.once="doThis"></a>
<!-- 핸들러 내 `event.preventDefault()`가 포함되었더라도 -->
<!-- 스크롤 이벤트의 기본 동작(스크롤)이 발생합니다. -->
<div @scroll.passive="onScroll">...</div>


- passive : 화면의 렌더링과 로직의 동작을 분리해서 처리 => 쾌적한 환경 제공

입력키 수식어
키보드 이벤트를 수신할 때, 특정 키를 확인해야 하는 경우가 많기 때문에, 키 수식어를 지원
<!-- `key`가 `Enter`일 때만 `submit`을 호출합니다 -->
<input @keyup.enter="submit" />
KeyboardEvent.key를 통해 유효한 입력키 이름을 kebab-case로 변환하여 수식어로 사용
<input @keyup.page-down="onPageDown" />
위의 예에서 핸들러는 $event.key가 'PageDown'일 경우에만 호출
입력키 별칭
Vue는 가장 일반적으로 사용되는 키에 대한 별칭을 제공
.enter / .tab / .delete ("Delete" 및 "Backspace" 키 모두 캡처) / .esc / .space / .up / .down / .left / .right
시스템 입력키 수식어
마우스 또는 키보드 이벤트 리스너는 아래 수식어를 사용하여, 해당 입력키를 누를 때만 트리거 되도록 할 수 있다.
.ctrl / .alt / .shift / .meta
.left / .right / .middle

왜 html로 된 리스너를 사용하는가?
- html 템플릿을 간단히 해서 js 코드 내에서 핸들러 함수 구현을 찾는 것이 더 쉽다.
- js에서 이벤트 리스너를 수동으로 연결할 필요가 없으므로 뷰모델 코드는 순수 로직과 DOM이 필요하지 않다. 테스트가 쉬워짐.
- 뷰모델이 파기되면 모든 이벤트 리스너가 자동으로 제거 된다. 이벤트 제거에 대한 걱정이 필요없어짐.
폼 입력 바인딩
프론트엔드에서 폼을 처리할 때, 폼 입력 엘리먼트의 상태를 JavaScript의 상태와 동기화해야 하는 경우가 많다.
<input
:value="text"
@input="event => text = event.target.value">
// 아래처럼 바꿀 수 있다.
<input v-model="text">
- 텍스트 유형의 <input>과 <textarea> 경우, value 속성과 input 이벤트를 사용한다.
- <input type="checkbox">과 <input type="radio"> 경우, checked 속성과 change 이벤트를 사용한다.
- <select>는 value를 속성으로 사용하고 change를 이벤트로 사용한다.
사용법
텍스트
<p>메세지: {{ message }}</p>
<input v-model="message" placeholder="메세지 입력하기" />
한국어는 v-model이 업데이트되지 않는다. 대신 직접 구현한 input 이벤트 리스너와 value 바인딩을 사용해 기능을 구성해야 한다.

여러 줄 텍스트
<span>여러 줄 메세지:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<textarea v-model="message" placeholder="여러 줄을 추가해보세요"></textarea>
<textarea> 내부에 이중 중괄호 문법은 작동하지 않으므로 v-model을 사용
<!-- 잘못된 사례 -->
<textarea>{{ text }}</textarea>
<!-- 올바른 사례 -->
<textarea v-model="text"></textarea>
체크박스
단일 체크박스는 불리언을 값을 사용
<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>
배열 또는 Set에 여러 개의 체크박스 값을 바인딩할 수도 있다.
const checkedNames = ref([])
<div>체크된 이름: {{ checkedNames }}</div>
<input type="checkbox" id="jack" value="젝" v-model="checkedNames">
<label for="jack">젝</label>
<input type="checkbox" id="john" value="존" v-model="checkedNames">
<label for="john">존</label>
<input type="checkbox" id="mike" value="마이크" v-model="checkedNames">
<label for="mike">마이크</label>
라디오
<div>선택한 것: {{ picked }}</div>
<input type="radio" id="one" value="하나" v-model="picked" />
<label for="one">하나</label>
<input type="radio" id="two" value="둘" v-model="picked" />
<label for="two">둘</label>
셀렉트
단일 셀렉트
<div>선택됨: {{ selected }}</div>
<select v-model="selected">
<option disabled value="">다음 중 하나를 선택하세요</option>
<option>가</option>
<option>나</option>
<option>다</option>
</select>
다중 선택(배열로 바인딩 됨)
<div>선택됨: {{ selected }}</div>
<select v-model="selected" multiple>
<option>가</option>
<option>나</option>
<option>다</option>
</select>

수식어
.lazy
기본적으로 v-model은 각 input 이벤트 이후 데이터와 입력을 동기화한다.
대신 change 이벤트 이후에 동기화하기 위해 .lazy 수식어를 추가할 수 있다.
<!-- "input" 대신 "change" 이벤트 후에 동기화됨 -->
<input v-model.lazy="msg" />
.number
사용자 입력이 자동으로 숫자로 유형 변환되도록 하려면, v-model 수식어로 .number를 추가
<input v-model.number="age" />
값을 parseFloat()로 파싱할 수 없으면 원래 값이 대신 사용된다.
인풋에 type="number"가 있으면 .number 수식어가 자동으로 적용된다.
.trim
사용자 입력의 공백이 자동으로 트리밍되도록 하려면 v-model 수식어로 .trim을 추가하면 된다
<input v-model.trim="msg" />
'데브코스 프론트엔드 5기 > Vue' 카테고리의 다른 글
| 231120 [Day 45] Vue (1) (2) | 2023.11.21 |
|---|