Single File Component
번들링(Bundling)
Vite 기반의 도구
src 작업 폴더src/main.js 진입점(entry point)App.vue 컴포넌트
"type": "module" ES 모듈"build": "vite build" (펙킹, 번들링) 배포본 제작"dev": "vite" 평상시에는 develop으로"dependencies" 실제 배포용에서 필요“devDependencies” 배포할때는 필요없다(개발 과정에서만 필요)
`npm run dev`
모듈 경로 표기법 설정
@기호를 src 폴더로 인식시켜 절대 경로 사용
vscode에서 @기호 인식시키기

핵심 파일들-진입점
App.vue 파일 열었더니 설치하라고 나오는 팝업
설치전
설치후
App.vue
import 할 때에는 Helloworld로
<HelloWorld> & <hello-world> 같은 의미(둘다 사용 가능)
단일 파일 컴포넌트
App.vue → 컴포넌트 진입
<template /> 다양한 디렉티브와 보간법을 사용해 컴포넌트가 렌더링할 템플릿 작성
<script /> 컴포넌트 내부에서 사용할 Vue 컴포넌트 내부의 옵션 정의
<style /> 컴포넌트가 사용할 스타일 지정
간단한 단일 컴포넌트 작성과 사용
CheckboxItem 컴포넌트 만들기
<template>
<li><input type="checkbox" v-model="checked" />옵션1</li>
</template>
<script>
export default {
name: 'CheckboxItem',
data() {
return {
checked: false,
};
},
};
</script>
컴포넌트를 사용하기 위해선 먼저 등록을!
src/main.js에서 만든 루트 Vue 인스턴스에 등록
import CheckboxItem from './components/CheckboxItem.vue';
createApp(App)
.component('CheckboxItem', CheckboxItem)
.mount('#app');
사용할 컴포넌트 import
components 옵션에 해당 컴포넌트 지정
<script>
import CheckboxItem from './components/CheckboxItem.vue';
export default {
name: 'App',
components: { CheckboxItem }, // 지역컴포넌트
};
</script>
src/App.vue
<CheckboxItem /> 사용자 정의 태그로 사용
<template>
<div>
<h2>App 컴포넌트</h2>
<hr />
<ul>
<CheckboxItem />
<CheckboxItem />
<CheckboxItem />
<CheckboxItem />
</ul>
</div>
</template>
❗️http://localhost:XXXX 링크 이동했을 때 아래와 같은 에러가?

Vue의 Single File Component(SFC)에서는 <template> 요소가 하나만 포함되어야 한다. 그렇지 않으면 "Single file component can contain only one <template> element" 오류가 발생
여러 컴포넌트들을 조합하여 애플리케이션을 개발하면 컴포넌트 간의 정보의 전달이 필요하다. 이러한 정보의 전달은 속성(props)과 이벤트(event)를 이용한다.
컴포넌트들은 속성(Props)을 통해서 자식 컴포넌트로 정보를 전달할 수 있다. 전달 방향은 부모에서 자식으로만 향한다.
자식 컴포넌트에서 부모 컴포넌트로 정보를 전달할 때는 이벤트를 이용한다. 자식 컴포넌트는 부모 컴포넌트로 이벤트를 발신(emit)할 수 있다. 자식 컴포넌트에서 사용자 정의 이벤트를 정의하고 이벤트를 발생시키면 부모 컴포넌트에서 이벤트 핸들러 메서드를 호출하도록 작성한다. 속성 전달과 이벤트 발신이 부모-자식 컴포넌트 간의 정보를 전달하는 기본적인 방법이다.
속성을 이용한 정보 전달
<template>
<li><input type="checkbox" :checked="checked" />{{ name }}</li>
</template>
<!-- 속성을 이용한 정보 전달 -->
<script>
export default {
name: 'CheckboxItem',
props: ['name', 'checked'], // 속성명을 배열로 정의
// => props 옵션으로 전달받을 속성을 정의
// 부모 컴포넌트로부터 속성을 전달받도록! (속성을 이용한 정보 전달)
};
</scrip
<CheckboxItem
v-for="idol in idols"
:key="idol.id"
:name="idol.name"
:checked="idol.checked"
/>
:name="idol.name"
:checked="idol.checked"
<!-- 개별적인 속성 값 하나하나를 v-bind 디렉티브로 전달-->
<template>
<li><input type="checkbox" :checked="idol.checked" />{{ idol.name }}</li>
</template>
<!-- 속성을 이용해 객체 전달하기(기본 타입의 값이 아닌 객체나 배열을 전달할 수 있다!) -->
<script>
export default {
name: 'CheckboxItem2',
props: ['idol'],
};
</script>
<!-- name, checked 속성 대신에 idol 이라는 속성을 전달받도록 변경 -> 속성으로 객체를 전달받을 것 -->
<CheckboxItem v-for="idol in idols" :key="idol.id" :idol="idol" />
속성 변경
기본값 속성
참조 타입 속성
속성(props)으로 전달받은 값은 읽기 전용의 값
→ 기본 타입(primitive type)인 경우 자식 컴포넌트에서 변경할 수 없으며, 객체나 배열과 같은 참조 타입인 경우라도 변경할 수는 있지만 변경하지 않을 것을 권장
→ 속성의 목적은 자식 컴포넌트가 필요한 데이터를 속성으로 전달받아 UI를 렌더링하기 위함
객체를 속성으로 전달하는 경우는 속성을 변경할 수 있다.
→ 객체나 배열은 참조형이기 때문에 객체, 배열의 메모리 주소가 바뀌지 않고 내부 속성만 변경이 되는 경우라면 속성으로 전달한 값은 바뀌지 않은 것으로 간주되기 때문에 변경할 수 있다. 하지만 속성의 본래 목적에 위배되는 것이므로 권장하지 않는다.
속성의 유효성 검증
<!-- 속성의 유효성 검증 -->
<template>
<li><input type="checkbox" :checked="checked" />{{ id }} - {{ name }}</li>
</template>
<script>
export default {
name: 'CheckboxItem',
props: {
id: [Number, String], // Number 또는 String 타입
name: String, // String 타입
checked: {
type: Boolean, // Boolean 타입
required: false, // 옵션
default: false, // 생략시, 기본값은 false
},
},
};
</script>
<template>
<div>
<h2>관심있는 K-POP 가수?</h2>
<hr />
<ul>
<CheckboxItem
v-for="idol in idols"
:key="idol.id"
:id="idol.id"
:name="idol.name"
:checked="idol.checked"
/>
</ul>
</div>
</template>
<script>
import CheckboxItem from './components/CheckboxItem3.vue';
export default {
name: 'App',
components: { CheckboxItem },
data() {
return {
idols: [
// { id: 1, name: 'BTS', checked: true },
// { id: 2, name: 'Black Pink' },
// { id: 3, name: 'EXO' },
// { id: 4, name: 'ITZY' },
// checked 값이 없는 아이템 존재 => checked 속성이 전달되지 않으면 기본값인 false를 부여하도록 CheckboxItem3 컴포넌트 예제에서 지정
// 유효성에 어긋나는 값을 속성으로 전달
{ id: 1, name: '이름1', checked: true },
{ id: 2, name: '이름2', checked: 1 },
{ id: 3, name: '이름3' },
{ id: 4, name: { special: '이름4' } },
],
};
},
};
</script>
에러 분석: Invalid prop: type check failed
이 에러는 부모 컴포넌트에서 자식 컴포넌트(CheckboxItem.vue)로 전달하는 props 타입이 올바르지 않아서 발생한 것이다.
사용자 정의 이벤트를 이용한 정보 전달
컴포넌트 인스턴스의 $emit() 메서드 이용
$emit('이벤트명', [값])
이벤트명 → 사용자 정의
값 → 부모에게 전달
this.$emit('event-name', eventArgs1, eventArgs2, …)<child-component @event-name="handlerMethod" />
methods: {
handlerMethod(eventArgs1, eventArgs2, …) {
// 전달받은 아규먼트로 처리할 코드 작성
}
}이벤트의 발신을 위한 $emit() 내장 메서드는 직계 부모 컴포넌트로만 이벤트 정보를 전송한다. 컴포넌트 계층 구조가 복잡할 때는 중간에 거쳐가는 컴포넌트에서 이벤트 정보를 받아서 다시 부모로 전달해야 한다.
이벤트 유효성 검증
작성 안 하면 부모의 이벤트명과 다른 걸 적어서 작동이 안 될 때 에러가 안 떠서 왜인지 모르게 됨
emits: [ 'nameChanged1'],emits: {
namedChanged: (e) => { // 이벤트명
return e.name && typeof e.name === 'string' && e.name.trim().length >= 3
// e.name -> 입력 여부 체크
// type ~ 'string' -> 타입 체크
// e.name.trim()~ -> 길이 체크
? true
: false;
},
},
이벤트 에미터
→ 하나의 공유 이벤트 에미터(Event Emitter)를 만들어 특정 컴포넌트에게 이벤트를 전송
→ mitt 패키지 라이브러리 사용(잘 사용 안 함 , 존재 정도만 알아두기)
→ 상태 관리 툴 사용
1. 프로젝트 만드는 법(골격 이해)
2. 부모-자식 관계가 생기는데 부모가 자식한테 정보를 어떻게 전달? 프로퍼티 property(만드는 방법 알기)
3. 자식이 부모에게 정보 전달은? 이벤트로!