Vue 문법 정리 1 / Vue 3 템플릿 문법 (인터폴레이션, 디렉티브)
인터폴레이션 (Interpolation)
템플릿에서 데이터를 HTML이 아닌 일반 텍스트로 간단히 출력할 때 사용합니다.
Vue 데이터 바인딩 문법 중 하나이며, 데이터가 변경되면 템플릿이 다시 렌더링됩니다.
{{ data변수명 }}
아래와 같이, 간단한 JS 표현식도 사용 가능합니다.
<p>{{ count + 1 }}</p>
<p>{{ isTrue ? '참' : '거짓' }}</p>
<p>{{ data변수명.split('').reverse().join('') }}</p>
디렉티브 (Directive)
v- 접두사로 시작하는 Vue 내장 HTML 속성입니다.
컴포넌트 또는 DOM 요소에 특정 동작을 지시할 수 있습니다.
디렉티브 구성요소
디렉티브명:전달인자.수식어="값" |
전달인자, 수식어가 없으면 생략 가능합니다.
수식어가 여러 개면 연결해서 입력할 수 있습니다.
v-text
<span v-text="data변수명"></span>
데이터를 텍스트로 렌더링하는 아래 인터폴레이션과 동일한 역할을 합니다.
<span>{{ data변수명 }}</span>
v-html
<span v-html="data변수명"></span>
데이터를 일반 텍스트가 아닌 HTML로 렌더링합니다.
HTML 동적 렌더링 시 XSS (스크립트 삽입 공격) 이슈에 주의해야 합니다.
일반 사용자가 작성하거나 제공한 콘텐츠를 렌더링하면 안 됩니다.
v-once
<p v-once>{{ data변수명 }}</p>
데이터가 변경되어도 다시 렌더링되지 않는 일회성 바인딩입니다.
v-bind (:)
<div v-bind:title="data변수명">마우스오버</div>
또는
<input type="text" :disabled="data변수명"/>
이중 중괄호와 달리, HTML 속성에 동적으로 값을 바인딩할 수 있는 단방향 속성 바인딩입니다.
data가 변경되면 바인딩 된 DOM도 변경되지만, 사용자 입력으로 DOM이 변경되면 data는 변경되지 않습니다.
다중 속성 바인딩 예시
<template>
<input v-bind="attrs">
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const attrs = ref({
type: "text",
value: '123456',
disabled: false,
});
return {
attrs
}
}
}
</script>
위와 같이, 여러 속성을 가진 data 객체로 한 번에 다중 속성 바인딩이 가능합니다.
다중 클래스 바인딩 예시
<template>
// :class="클래스명: 조건"
<div class="기존클래스" :class="{ active: isActive, 'text-danger' : hasError }">텍스트</div>
// :class="클래스객체명"
<div class="기존클래스" :class="classObject">텍스트</div>
또는
<div class="기존클래스" :class="classObjectComputed">텍스트</div>
// :class="[클래스1, 클래스2, 클래스3]"
<div class="기존클래스" :class="[isActive ? 'active-class' : 'class', errorClass, classObject]">텍스트</div>
</template>
<script>
import { ref, reactive, computed } from 'vue';
export default {
setup() {
const isActive = ref(true);
const hasError = ref(false);
const classObject = reactive({
active: isActive.value,
'text-danger': hasError.value
});
// 각 class 조건이 여러개인 경우
const classObjectComputed = computed(() => {
return {
active: isActive.value,
'text-danger': hasError.value,
highlight: isActive.value && !hasError.value,
'bg-gray': !isActive.value && hasError.value
}
});
const errorClass = ref('error');
return { isActive, hasError, classObject, classObjectComputed };
}
}
</script>
<style>
.active {
font-weight: 900;
}
.text-danger {
color: red;
}
.highlight {
background-color: yellow;
color: black;
font-weight: bold;
}
.bg-gray {
background-color: #d3d3d3;
color: white;
}
</style>
위와 같이, 다양한 스타일을 입힐 수 있는 다중 클래스 바인딩도 가능합니다.
v-bind:class 내 클래스명에 특수문자가 있으면 ‘‘로 감싸야 합니다.
인라인 스타일 바인딩 예시
<template>
<div :style="styleObject">텍스트</div>
<button v-on:click="fontSize--">-</button>
<button v-on:click="fontSize++">+</button>
</template>
<script>
import { ref, computed } from 'vue';
export default {
setup() {
const fontSize = ref(13);
const styleObject = computed(() => {
return {
color: 'red',
fontsize: fontsize.value + 'px',
}
});
return {
styleObject
}
}
}
</script>
위와 같이, 인라인 스타일을 정의하고 바인딩 할 수도 있습니다.
동적 컴포넌트 (Dynamic Component)
<component :is="현재보여줄컴포넌트명"></component>
v-bind:is 속성을 사용하면 동적으로 컴포넌트를 전환할 수 있습니다.
현재 컴포넌트명을 저장하는 변수를 shallowRef 함수로 정의하면 성능이 더 좋습니다.
shallowRef는 객체 내부 값 변동을 추적하지 않기 때문입니다.
v-model
<input type="text" v-model="data변수명" />
<textarea v-model="data변수명"></textarea>
<select v-model="data변수명">
<option value="값1">값1<option>
<option value="값2">값2<option>
</select>
<label>
<input type="radio" name="라디오분류" value="값1" v-model="data변수명" />
<input type="radio" name="라디오분류" value="값2" v-model="data변수명" />
<label>
<input type="checkbox" v-model="data변수명" true-value="체크" false-value="미체크" />
<label>
<input type="checkbox value="값1" v-model="배열data변수명" />
값1
</label>
<label>
<input type="checkbox value="값2" v-model="배열data변수명" />
값2
</label>
<label>
<input type="checkbox value="값2" v-model="배열data변수명" />
값2
</label>
Vue에서 반응형 상태와 DOM 입력을 동기화 할 수 있는 양방향 바인딩 디렉티브입니다.
data가 변경되면 바인딩 된 DOM도 변경되고, 사용자 입력으로 DOM이 변경되면 data가 변경됩니다.
<input type="text" :value="data변수" @input="event => { data변수 = event.target.value }" />
텍스트 인풋 v-model 예시의 경우, 위 코드와 동일한 효과입니다.
v-model 수식어 종류
.lazy |
기본적으로 v-model은 input 이벤트 후 입력과 데이터를 동기화합니다. lazy 수식어를 사용하면 change 이벤트 후 (인풋에서 포커스가 나갔을 때) 동기화합니다. |
.number | 사용자 입력 시 number 타입으로 형변환 처리 |
.trim | 사용자 입력 시 앞, 뒤 공백 제거 처리 |
v-on (@)
<button v-on:click="이벤트함수명">Click</button>
또는
<button @click="이벤트함수명">Click</button>
<script>
const 이벤트함수명 = (event) => {
console.log(event.target);
console.log(event.target.tagName);
}
</script>
v-on 디렉티브는 클릭, 마우스 오버, 키다운 등 다양한 이벤트 처리를 위해 사용됩니다.
이벤트 핸들러 함수 실행 시, 매개변수로 event 객체를 받을 수 있습니다.
<button @click="이벤트함수명('매개변수', $event)">Click</button>
<script>
const 이벤트함수명 = (변수명, event) => {
console.log(event.target);
console.log(event.target.tagName);
}
</script>
위와 같이, 다른 매개변수와 함께 이벤트 객체를 넘길 수도 있습니다.
v-on 이벤트 수식어 종류
.stop | 겹쳐있는 요소들에 이벤트 전파를 방지하는 e.stopPropagation() 기능 |
.prevent | 요소가 가진 기본 기능 동작을 방지하는 e.preventDefault() 기능 |
.capture |
이벤트 리스너를 캡처링 모드로 실행 (캡처링 단계에서 이벤트 감지) 캡처링 : 요소들이 겹친 경우, 최상위 요소부터 하위 요소까지 내려가며 이벤트 전파 버블링 : 요소들이 겹친 경우, 하위 요소부터 최상위 요소까지 올라가며 이벤트 전파 |
.self | 겹친 요소가 클릭되어도, 이벤트 타겟이 본인 요소일 때만 동작 |
.once | 이벤트 함수가 한 번만 실행되고, 이후부터는 동작하지 않음</tr> |
.passive |
스크롤 등 모바일 터치 이벤트의 성능을 높이기 위해 사용 이벤트 리스너가 preventDefault()를 호출하지 않도록 DOM 이벤트에 { passive: true } 속성 추가 v-on:scroll.passive="onScroll" 형태로 자주 사용됨 |
.enter | Enter 키 입력 시 동작 |
.tab | Tab 키 입력 시 동작 |
.delete | Delete 키 입력 시 동작 |
.esc | Esc 키 입력 시 동작 |
.space | Space 키 입력 시 동작 |
.up | PgUp 키 입력 시 동작 |
.down | PgDn 키 입력 시 동작 |
.left | 왼쪽 방향키 입력 시 동작 |
.right | 오른쪽 방향키 입력 시 동작 |
.ctrl | Ctrl 키 입력 시 동작 |
.alt | Alt 키 입력 시 동작 |
.shift | Shift 키 입력 시 동작 |
.meta | Mac의 커맨드 키 또는 Windows의 윈도우 키 입력 시 동작 |
.left | 마우스 왼쪽 버튼 클릭 시 동작 |
.right | 마우스 오른쪽 버튼 클릭 시 동작 |
.middle | 마우스 스크롤 버튼 클릭 시 동작 |
텍스트
제목
본문
``` 템플릿을 사용하면 여러 HTML 요소를 조건에 따라 렌더링 할 수 있습니다. template은 div와 달리 렌더링 결과에 포함되지 않습니다. ### v-else ```텍스트1
텍스트2
``` 조건에 따라 다른 엘리먼트를 렌더링 할 때 사용합니다. ### v-else-if ```텍스트A
텍스트B
텍스트B
A, B, C가 아닙니다.
텍스트
-
// 배열 렌더링
<li v-for="(item, index) in items" :key="item.id">
{{ index }}, {{ item.message }}
</li>
// 객체 렌더링
<li v-for="(value, key, index) in myObject" :key="key">
{{ key }}, {{ value }}, {{ index }}
</li>
-
<li v-if="user.isActive" :key="users.id">
{{ user.name }}
</li>
{{ data변수명 }}