ch1. 프런트엔드 개발 흐름과 Vue
Webkit: Safari 브라우저의 HTML/CSS 렌더링 엔진
- Chrome 브라우저는 Webkit 기반으로 시작하여, Blink라는 Webkit에서 분기한 새로운 HTML/CSS 렌더링 엔진 채택
프레임워크 vs 라이브러리
라이브러리
- 편리한 코드를 모아놓은 것
- 라이브러리를 활용한 코드 작성은 개발자가 직접 수행 -> 애플리케이션 규모가 커질수록 코드가 복잡해지고 중복이 발생
- 어떤 동작을 제어하는 코드를 개발자가 작성하고 필요한 부분만 라이브러리를 사용
프레임워크
- 애플리케이션 작동에 필요한 정형화된 코드를 포함 -> 라이브러리를 활용한 코드 작성을 간소화
- 핵심 비즈니스 로직 구현에 집중하기 쉬움
- 어떤 동작을 제어하는 코드를 프레임워크에 맡김 -> 제어의 역전(IOC: Inversion of Control)
ch2. Vite와 Vue 프로젝트
Vue 공식문서의 스타일 가이드
https://vuejs.org/style-guide/
ch3. Vue 프로그래밍의 기본
Vue 프로젝트 폴더 구조
/dist: build 명령어로 만들어진 배포용 파일셋으로 distribution(배포)의 약자
- build 명령어는 프로젝트의 모든 파일(.vue 파일 포함)을 분석하여 브라우저에서 읽어들여 작동할 수 있는 파일들로 변환한다
/public: 별도의 변환을 거치지 않고 배포환경에도 그대로 적용되는 파일들이 존재
index.html: 개발 환경과 배포 환경의 파일이 서로 다름
- 개발 환경: root 위치의 index.html의 <script>가 main.ts 를 읽어들임 -> 실제 브라우저는 .js 만 읽을 수 있음
- 배포 환경: /dist내의 index.html의 <script>가 hash 처리된 .js 파일을 읽음
ch4. 데이터와 이벤트 디렉티브
디렉티브(directive): Vue의 템플릿 블록에서 사용가능한 v-로 시작하는 attribute
예) v-model: 양방향 데이터 바인딩
v-bind에서 바인딩할 attribute를 템플릿 변수로 지정하기
<template>
<img :src="logoImage" :[widthOrHeight]="value" alt="logo" />
</template>
<script setup lang="ts">
const widthOrHeight = ref<"width" | "height">("width");
const value = ref(0);
</script>
여러 attribute를 일괄적으로 바인딩하기
- 중복된 attribute가 있을 때는 뒤에 있는 attribute가 적용됨
<template>
<div>
<img v-bind="imgAttributes" alt="nuxt logo" title="nuxt" />
</div>
</template>
<script setup lang="ts">
const imgAttributes = ref({
src: "/favicon.ico",
alt: "logo",
width: 75,
height: 75,
title: "nuxt logo",
});
</script>
style attribute 바인딩 시 배열을 전달하기
- 중복된 css 프로퍼티가 있다면, 나중에 오는 프로퍼티가 적용된다
<template>
<div>
<h2 :style="styles1">안녕하세요1</h2>
<h2 :style="styles2">안녕하세요2</h2>
<h2 :style="[styles1, styles2]">안녕하세요3</h2>
</div>
</template>
<script setup lang="ts">
const styles1 = ref({
fontSize: "1.5rem",
});
const styles2 = ref({
fontSize: "2rem",
color: "pink",
});
</script>
class attribute 바인딩
- style class 지정을 boolean 값을 사용하여 선택적으로 지정할 수 있다
<template>
<div>
<h2 :class="{ 'text-color-pink': true }">안녕하세요1</h2>
<h2 :class="{ 'text-size-big': true }">안녕하세요2</h2>
<h2 :class="{ 'text-size-big': true, 'text-color-pink': true }">안녕하세요3</h2>
</div>
</template>
<style scoped>
.text-color-pink {
color: pink;
}
.text-size-big {
font-size: 3rem;
}
</style>
DOM 이벤트 단계(JavaScript 내용 복습)
- 예를 들어 아래와 같은 DOM 구조가 있을 때
<html>
<body>
<section>
<div>
<button>클릭</button>
</div>
</section>
</body>
</html>
1) 캡처링
- <button> element를 클릭해도, 가장 먼저 이벤트를 감지하는 것은 기본 window 객체임
- 그리고 차례대로 요소들 내부로 들어가서 이벤트 발생지까지 추적 -> 캡처링
2) 이벤트 타겟
- 최종적으로 이벤트 발생지가 파악되면, 발생지에 등록된 이벤트 핸들러가 호출됨
3) 버블링
- 이벤트 타겟에서 이벤트 핸들러가 호출되고 나면, 캡처링 과정 역순으로 부모 요소로 거슬러 올라감(window 객체까지) -> 버블링
이벤트 전파
- 버블링 과정에서 각 요소에 부착된 이벤트 핸들러가 호출됨 -> 이벤트 전파
- 설정을 변경하면 캡쳐링 단계에서도 이벤트 핸들러를 호출시킬 수 있음
- 예시 (클릭 이벤트 전파 확인하기)
<template>
<div class="4f" @click="handleClick">
<div class="3f" @click="handleClick">
<div class="2f" @click="handleClick">
<button
class="1f"
:style="{ padding: '10px', color: 'red' }"
@click="handleClick"
>
클릭
</button>
</div>
</div>
</div>
</template>
<script setup lang="ts">
const handleClick = (e: MouseEvent) => {
console.log(e.currentTarget); // 버블링 단계에서 각 부모 요소
// console.log(e.target); // event 발생지 근원
};
</script>
- 결과 (버블링): target 부터 쭉 거슬러 올라감
v-on 디렉티브 수식어
- .stop(stopPropagation): 이벤트 전파를 방지하여 버블링 단계에서 부모 element들의 추가적인 이벤트 핸들러 호출 방지
- .capture: 캡쳐링 단계에서만 해당 이벤트 핸들러 호출하고 버블링 단계에서는 호출하지 않음
- .self: 해당 element가 target일 때만 이벤트 핸들러 실행 (버블링이나 캡쳐링에서 이벤트 핸들러 호출X)
- .prevent(preventDefault)
- .passive: preventDefault의 반대로 즉시 이벤트 처리
클릭 이벤트와 키 이벤트 수식어
- v-on 디렉티브의 수식어 중 클릭 이벤트와 키 이벤트에는 전용 수식어가 제공됨
- 키 입력 이벤트 중 keypress는 deprecate되어 keydown을 사용하면 됨
- 예시
<template>
<div>
<h2>{{ msg }}</h2>
<input type="text" @keydown.enter="onEnterKey" />
<br />
<button @click.right="onRightButtonClick">마우스 우클릭</button>
<br />
<button @click.shift="onShiftClick">시프트 키를 누르면서 클릭</button>
<br />
</div>
</template>
<script setup lang="ts">
const msg = ref("시작 전");
const onEnterKey = () => {
msg.value = "엔터 키가 입력되었습니다";
};
const onRightButtonClick = () => {
msg.value = "마우스 우클릭되었습니다";
};
const onShiftClick = () => {
msg.value = "시프트 키를 누르면서 클릭했습니다";
};
</script>
키 이벤트 수식어
- 특정 알파벳을 수식어로 사용 가능 (예 - @keydown.q="")
- 이외에 enter, tab, space, delete, esc, up, down, left, right 사용 가능
클릭 이벤트 수식어
- left: 마우스 왼쪽 버튼
- right: 오른쪽
- middle: 가운데 버튼
시스템 수식어
- ctrl: 컨트롤 키
- alt: 알트 키
- shift: 시프트 키
- meta: Mac에서는 커맨드 키, Windows에서는 Win 키
=> 클릭 이벤트와 조합 가능 (예 - 시프트 누르고 클릭 @click.shift="")
알파벳 키와는 조합 불가
exact 수식어
- 조합하여 클릭되거나 키 눌리는 것을 방지 (예 - @keydown.alt.exact="")