728x90
Component (컴포넌트)
- 기본 HTML 엘리먼트를 확장하여 재사용 가능한 코드를 캡슐화하는데 도움을 줌
- CS에서는 다시 사용할 수 있는 범용성을 위해 개발된 소프트웨어 구성 요소를 의미
- 유지보수, 재사용성 up
- Vue 컴포넌트 === Vue 인스턴스
SFC (Singel File Component)
- Vue 컴포넌트 기반 개발의 핵심 특성
- 하나의 컴포넌트는 .vue 확장자를 가진 하나의 파일 안에서 작성되는 코드의 결과물
- 화면의 특정 영역에 대한 HTML, CSS, JavaScript 코드를 하나의 파일(.vue)에서 관리
- Vue 컴포넌트 === Vue 인스턴스 === .vue 파일
Vue Component 구조
- 한 화면 안에서도 기능 별로 각기 다른 컴포넌트 존재 (하나의 컴포넌트는 여러 개의 하위 컴포넌트 가질 수 있음)
- Vue component는 const app = new Vue({...})의 app을 의미, 이는 Vue의 인스턴스
- 컴포넌트 기반 개발이 반드시 파일 단위로 구분되어야 하는 것은 아님!!
- 단일 .html 파일 안에서도 여러 개의 컴포넌트를 만들어 개발 가능
- Vue app은 자연스럽게 중첩된 컴포넌트 트리로 구성됨
- 컴포넌트 간 부모-자식 관계 구성됨
- 부모는 자식에게 '데이터'를 전달 : pass props
- 자식은 자신에게 일어난 일을 부모에게 '메시지' 알림 : emit event
- 템플릿 (HTML)
- HTML의 body 부분
- 각 컴포넌트를 작성
- 스크립트 (JavaScript)
- JavaScript가 작성되는 곳
- 컴포넌트 정보, 데이터, 메서드 등 vue 인스턴스를 구성하는 대부분이 작성됨
- 스타일 (CSS)
- CSS가 작성되며 컴포넌트 스타일을 담당
Component 등록
<!-- Parent.vue -->
<template>
<div>
<!-- 3. 보여주기 -->
<!-- <child></child> -->
<child/>
</div>
</template>
<script>
// 1. 불러오기
import Child from '@/components/Child.vue'
export default {
name: 'Parent',
components: {
// 2. 등록하기
Child
},
}
</script>
Props
- 부모(상위) 컴포넌트의 정보(데이터)를 전달하기 위한 사용자 지정 특성
- 자식(하위) 컴포넌트는 props 옵션을 사용하여 수신하는 props를 명시적으로 선언해야 함
- 모든 컴포넌트 인스턴스에는 자체 격리된 범위가 있음 (자식 컴포넌트 템플릿에서 상위 데이터를 직접 참조 불가)
- props 이름 컨벤션
- during declaration (선언 시) : camelCase
- in template (HTML) : kebab-case
1. 자식 컴포넌트에 보낼 props 데이터 선언
<!-- Parent.vue -->
<template>
<div>
<!-- 작성법 : prop-data-name="value" -->
<child
my-message="Hello!"
/>
</div>
</template>
<script>
import Child from '@/components/Child.vue'
export default {
name: 'Parent',
components: {
Child
},
}
</script>
2. 수신할 데이터를 명시적으로 선언 후 사용
<!-- Child.vue -->
<template>
<div>
<!-- 사용 -->
<p>{{ myMessage }}</p>
</div>
</template>
<script>
import Child from '@/components/Child.vue'
export default {
name: 'Child',
// 선언
props: {
myMessage: String,
},
}
</script>
- 동적으로 props 작성하기
<!-- Parent.vue -->
<template>
<div>
<child
:my-message="Hello!"
/>
</div>
</template>
<script>
import Child from '@/components/Child.vue'
export default {
name: 'Parent',
components: {
Child
},
data: function () {
return {
myMessage: 'This is parent Data by v-bind'
}
},
}
</script>
- v-bind directive를 사용해 부모 데이터의 props를 동적으로 바인딩
- 부모에서 데이터가 업데이트 될 때마다 자식 데이터로도 전달
- 컴포넌트의 data는 반드시 함수여야 함!
- 기본적으로 각 인스턴스는 모두 같은 data 객체를 공유하므로 새로운 data 객체를 반환해야 함
- 그렇지 않으면 각 인스턴스가 모두 같은 data 객체를 공유하게 됨
- props시 숫자를 전달하려면 v-bind를 사용해야함
<!-- 일반 문자열 "1"을 전달 -->
<comp some-prop="1" />
<!-- 실제 숫자로 전달 -->
<comp :some-porp="1" />
Emit event
- 모든 props는 하위 속성과 상위 속성 사이의 단방향 바인딩 형성
- 부모의 속성이 변경되면 자식 속성에게 전달되지만, 반대 방향으로는 안 됨
(자식 요소가 부모 요소의 상태를 변경하는 경우 방지) - $emit(eventName)
- 현재 인스턴스에거 이벤트를 트리거
- 추가 인자는 리스너의 콜백 함수로 전달
- 부모 컴포넌트는 자식 컴포넌트가 사용되는 템플릿에서 v-on을 사용하여 자식 컴포넌트가 보낸 이벤트 청취
- event 이름 컨벤션
- 컴포넌트, props와 달리 자동 대소문자 변환 제공 x
- HTML의 대소문자 구분을 위해 DOM 템플릿의 v-on 이벤트 리스너는 항상 소문자로 변환
- 이러한 이유로 이벤트 이름은 항상 kebab-case
1. $emit 인스턴스 메서드 사용하여 이벤트 트리거
<!-- Child.vue -->
<template>
<div>
<input
@keyup.enter="ChildInputChange"
v-model="childInput"
>
</div>
</template>
<script>
import Child from '@/components/Child.vue'
export default {
name: 'Child',
data: {
return {
childInput: null,
}
},
props: {
myMessage: String,
},
methods: {
childInputChange: function () {
this.$emit('child-input-change', this.childInput)
},
},
}
</script>
2. 부모 컴포넌트는 자식 컴포넌트가 사용되는 템플릿에서 v-on를 사용하여 이벤트 청취
<!-- Parent.vue -->
<template>
<div>
<child
:my-message="Hello!"
@child-input-change="parentGetChange"
/>
</div>
</template>
<script>
import Child from '@/components/Child.vue'
export default {
name: 'Parent',
components: {
Child
},
data: function () {
return {
myMessage: 'This is parent Data by v-bind'
}
},
methods: {
parentGetChange: function (inputData) {
console.log(`Child로부터 ${inputData} 받음!`)
},
},
}
</script>
728x90
'PROGRAMMING > Vue' 카테고리의 다른 글
[Vue] Router (0) | 2021.11.21 |
---|---|
[Vue] Vue CLI (0) | 2021.11.20 |
[Vue] Lifecycle Hooks, lodash (0) | 2021.11.15 |
[Vue] Template Syntax (0) | 2021.11.15 |
[Vue] MVVM Pattern, Vue 인스턴스 생성 (0) | 2021.11.15 |
댓글