이재웅
컴포넌트 등록
전역 등록
과 지역 등록
으로 나뉜다.- 전역 등록
const app = Vue.createApp({...}); app.component('component-name', { ... });
전역 등록
은 모듈 번들러 같은 빌드 시스템을 이용할 때, 컴포넌트를 사용하지 않더라도 최종 빌드에 계속 포함되기 때문에 비효율적이다.- 지역 등록
const componentA = {...}; const componentB = {...}; const componentC = {...}; const app = Vue.createApp({ components: { 'component-name': componentA, 'component-name': componentB, 'component-name': componentC, } });
component-name
에 속하는 key
가 컴포넌트의 이름이 되며, value
가 참조하는 컴포넌트가 된다.등록된 컴포넌트는 해당 스코프 안에서
<component-name><component-name/>
형태로 사용이 가능하다.<div id="components"> <button-counter></button-counter> <button-counter></button-counter> <button-counter></button-counter> </div>
Props
- 컴포넌트에는
props
라는Array
형태의 특수한property
가 있으며,props
에 배열에 정의된property
를 이용해서 값을 전달받아 컴포넌트의 재사용성을 늘릴 수 있다.
v-bind
디렉티브를 이용해서 동적props
전달이 가능하다.
<div id="blog-posts-demo"> <blog-post v-for="post in posts" :key="post.id" :title="post.title" ></blog-post> </div>
커스텀 이벤트
- 이벤트 이름은 항상
kebab-case
를 사용하는 것이 권장된다.
v-on
디렉티브를 이용해서 커스텀 이벤트 등록이 가능하며, 하위 컴포넌트의 이벤트를 수신한다.
- 하위 컴포넌트에서는
$emit('event-name[, argument]')
문법을 이용해서 이벤트를 트리거 한다.
$emit
메서드의 두 번째parameter
로argument
를 전달했다면 이벤트에 값을 전달할 수 있으며, 이벤트 핸들러를 등록한 곳에서$event
를 이용해 값에 접근이 가능하다.
$emit
메서드에argument
를 전달했을 때, 이벤트 핸들러가 메서드 형태라면 첫 번째parameter
로 값이 전달된다.
emit
된 이벤트는 컴포넌트의emits
프로퍼티를 이용해 검사가 가능하다.
컴포넌트에서
<slot>
태그를 이용하면 컴포넌트의 content
를 컴포넌트 내부로 전달할 수 있다.동적 컴포넌트는
<component>
태그에 v-bind:is
디렉티브를 이용해서 생성할 수 있다.장규범
컴포넌트
특징
컴포넌트는 Vue의 강력한 기능 중 하나
재사용 가능한 코드를 캐슐화하는데 도움
Vue 컴포넌트는 Vue 인스턴스이기도 함, 모든 옵션 객체를 사용할 수 있음
키워드
- 전역 등록
- 지역 등록 ⇒ 인스턴스 옵션으로 등록함으로써 다른 인스턴스 컴포넌트 범위에서만 사용 가능한 컴포넌트 만들 수 있음
- DOM 템플릿 구문 분석 경고
- data는 반드시 함수(컴포넌트 인스턴스의 함수)
- 컴포넌트 인스턴스가 모두 같은 data 객체를 공유하게 되면 X
⇒ 새로운 데이터 객체를 반환하도록 해야함
- 컴포넌트 작성
- 컴포넌트는 부모 자식 관계에서 함께 함께 사용하기 위한 것(?) ⇒ 번역이 조금 이상하네요!
- 부모는 자식에게 데이터를 전달해야 할 수도 있으며, 자식은 자신에게 일어난 일을 부모에게 알릴 필요가 있음
- 가능한 분리된 상태로 유지하여 코드를 분리하여 작성하도록 해야함, 유지관리가 쉽고 쉽게 재사용할 수 있음
- Vue.js에서 부모-자식 컴포넌트 관계는 props는 아래로, events 위로

- Props로 데이터 전달하기
- 모든 컴포넌트 인스턴스에는 격리된 범위가 있음
- 하위 컴포넌트의 템플릿에서 상위 데이터를 직접 참조할 수 없고 그렇게 하면 안됨
⇒ props 사용
Vue.component('child', { // props 정의 props: ['message'], // 데이터와 마찬가지로 prop은 템플릿 내부에서 사용할 수 있으며 // vm의 this.message로 사용할 수 있습니다. template: '<span>{{ message }}</span>' }) <child message="안녕하세요!"></child>
- camelCase vs kebab-case
- HTML은 대소문자 구분 X ⇒ 템플릿 사용할 때 케밥 케이스 써야됨
Vue.component('child', { // JavaScript는 camelCase props: ['myMessage'], template: '<span>{{ myMessage }}</span>' }) <!-- HTML는 kebab-case --> <child my-message="안녕하세요!"></child>
- 동적 Props v
- -bind 사용하여 부모의 데이터에 props를 동적으로 바인딩
- 데이커가 상위에서 업데이트 될 때마다 하위 데이터로도 전달됨
- 객체의 모든 속성을 props로 전달하려면 인자없이 v-bind를 사용해서 객체를 전부 전달할 수 있음.
- 단방향 바인딩
- 상위 속성이 업데이트 되면 하위로 흐르게 되지만 반대는 안됨
⇒ 컴포넌트가 실수로 부모의 상태를 변경하여 앱의 데이터 흐름을 추론하기 어렵게 만드는 것을 방지 할 수 있음
- Prop 검증
- 유효성 검사 요구사항이 있는 객체를 사용할 수 있음
- type은 String, Number, Boolean, Function, Object, Array, Symbol
- Props가 아닌 속성
- ?? 부트스트랩 플러그인으로 써드 파티 컴포 사용할 경우
- 존재하는 속성 교체/ 병합
- v-on을 이용한 사용자 지정 이벤트
- .sync 수식어
- 컴포넌트의 v-model 사용자 정의 비-부모-자식간 통신
- 슬롯을 사용한 컨텐츠 배포
- 범위 컴파일
- 단일 슬롯
- 이름을 가지는 슬롯
- 범위를 가지는 슬롯
- 동적 컴포넌트
- 기타
- 재사용 가능한 컴포넌트 제작
- 자식 컴포넌트 참조
- 비동기 컴포넌트
- 고급 비동기 컴포넌트
- 컴포넌트 이름 규약
- 재귀
- 컴포넌트 사이의 순환 참조
- 인라인 템플릿
- x-templates
- v-once
팽건우
component 사용
html
의 위치만 알 수 있으면 mount
를 통해 재 사용할 수 있습니다.(data, computed, watch, methods
와 라이프사이클 훅과 같은 루트 인스턴스 재사용 허용<div id="components-demo"> <button-counter></button-counter> </div>
const app = Vue.createApp({}) // Define a new global component called button-counter app.component('button-counter', { data() { return { count: 0 } }, template: ` <button v-on:click="count++"> You clicked me {{ count }} times. </button>` }) app.mount('#components-demo')
Props를 이용하여 자식 component 에게 데이터 전달
Props는 컴포넌트에 등록할 수 있는 커스텀 속성으로 값이 전달되면 그 값은 해당 컴포넌트 인스턴스의 속성이 된다.
하위 컴포넌트 이벤트 수신을 하기 위해서는
v-on
, @
, $emit
를 사용하여 문제를 해결할 수 있습니다.홍정기
컴포넌트 등록
- 전역 등록
- 지역 등록: 각각의 컴포넌트 하위에 등록하는 것 같음
const ComponentA = { ... } const ComponentB = { components: { 'component-a': ComponentA } ... }
app.component
를 사용해 전역에 컴포넌트를 등록할 수 있는데 이는 규모가 커지면 단점이 생김.- 전역 정의 모든 컴포넌트마다 고유한 이름을 가져야만 합니다
- 문자열 템플릿 구문 강조가 부족하고, 여러 줄의 HTML을 위해 예쁘지 않은 슬래쉬 사용해야 합니다.
- CSS가 지원되지 않음 HTML과 JavaScript는 컴포넌트로 모듈화되지만 CSS는 제외됩니다(conspicuously left out).
- 빌드 단계가 없음 Pug(이전의 Jade)나 Babel 같은 전처리기보다 HTML과 ES5 JavaScript를 사용하는데 제한됩니다.
그래서 싱글 파일 컴포넌트를 사용하는데 이 형태가 저번에 규범님이 보여주신 파일 구조랑 똑같음.
props
옵션을 사용해 컴포넌트에 데이터를 전달할 수 있음.app.component('custom-component', { props: ['title'], template: `<h1>{{ title }}</h1>` }
<custom-component title="hello!"></custom-component>
v-bind
를 사용해 props
를 동적으로 전달할 수 있음.부모 컴포넌트는 하위 컴포넌트의 이벤트를 수신할 수 있음. 하위 컴포넌트에서
v-on
을 사용해 이벤트를 정의하고 그 이벤트에서 $emit()
함수를 실행해서 부모 컴포넌트로 이벤트를 전달한다. 함수의 두 번째 인자로 특정 값을 전달할 수 있는데 해당값은 $event
를 사용해 접근 가능함.페이지 약간 번역이 아쉽네...
slot
은 뭔가 리액트에서 children 같은 느낌인가component
엘리먼트의 is 속성을 사용해 is에 등록한 값이 변경되면 컴포넌트가 변경된다. is 속성에는- 이미 등록된 컴포넌트의 이름
- 컴포넌트의 옵션 객체
를 사용할 수 있다.