Vue 컴포넌트란 ?
블록과 같은 것이라고 이해하면 편하다
컴포넌트라는 블록을 조합하여, 화면을 구성할 수 있다
[ 참고 블로그 ]
[Vue.JS] 컴포넌트 (기본)
이번 포스트에서는 SPA에서 가장 중요하다 이야기 되는 컴포넌트에 관해 이야기 할 것입니다. 1. 기본 예제 // Define a new component called button-counter Vue.component('button-counter', { data: function () { return { coun
beomy.tistory.com
1. 컴포넌트의 기본 형태
// Define a new component called button-counter
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button @click="count++">You clicked me {{ count }} times.</button>'
});
// Vue 컴포넌트의 사용 형태
<div id="app">
<button-counter><button-counter/>
</div>
위 형태와 같이 컴포넌트 사용이 가능하다
컴포넌트를 생성할 때 사용되는 new Vue 옵션(data, computed, watch, methods)과
동일 하지만 el 옵션은 사용할 수 없습니다
2. 컴포넌트의 재사용
컴포넌트는 원하는 만큼 재사용 가능한 특징이 있습니다
// Define a new component called button-counter
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: '<button @click="count++">You clicked me {{ count }} times.</button>'
});
// Vue 컴포넌트의 사용 형태
<div id="app">
<button-counter><button-counter/> // count : 0
<button-counter><button-counter/> // count : 0
<button-counter><button-counter/> // count : 0
</div>
단, 위와 같이 동일한 컴포넌트를 여러번 호출하여도 해당 컴포넌트의 data 안의 count는 전부 따로 존재합니다
JAVA의 동일 클래스의 객체를 여러개 만들어도 같은 데이터가 아닌것과 동일합니다
3. 컴포넌트의 구조와 등록
Vue의 컴포넌트는 트리 형태로 중첩되어 사용됩니다
예를 들어, 헤더와 사이드바, 콘텐츠 영역은 포스트 등 모두 다른 컴포넌트로 구성되어 집니다
Vue에서 template에 컴포넌트가 사용되기 위해서는 Vue가 알수 있도록 등록되어야합니다
컴포넌트의 등록 방법은 전역, 로컬 방식 두가지 방법이 있습니다
전역은 모든 곳에서 사용가능한 방식이며, 로컬은 해당 인스턴스에서만 사용가능한 방식입니다
(1) 전역 컴포넌트 등록
Vue.component('my-component-name', {
// ... options ...
})
// 위 방식을 사용하여 전역에 컴포넌트를 등록 할 경우, 모든 Vue 인스턴스에서 컴포넌트 사용이 가능합니다
(2) 로컬 컴포넌트 등록
// 1. 로컬 컴포넌트 등록
var ComponentA = { /* ... */ }
var ComponentB = {
components: {
'component-a': ComponentA
},
// ...
}
// 2. 로컬 컴포넌트 등록
// import는 main js에 사용
// ComponentA는 컴포넌트의 이름 / from 의 데이터는 해당 Vue 파일 데이터
import ComponentA from './ComponentA.vue'
// 등록
export default {
components: {
ComponentA
},
// ...
}
4. props 사용하기
props는 부모 컴포넌트에서 자식 컴포넌트로 데이터 전달을 하기 위해 흔히 사용됩니다
props는 data와 유사하게 사용 가능한 속성입니다
Vue.component('blog-post', {
props: ['title'],
template: '<h3>{{ title }}</h3>'
})
// 위의 예제와 같이 props를 정의하면 정의한 이름으로 template에 사용 가능합니다.
// props로 원하는 만큼전달하여 사용할 수 있으며, 모든 값을 props로 전달 가능합니다.
<blog-post title="My journey with Vue"></blog-post>
<blog-post title="Blogging with Vue"></blog-post>
<blog-post title="Why Vue is so fun"></blog-post>
// 즉 해당 title 들이 template에 데이터로 들어간다
---------------------------------------------------------------------------------------------
// 1
<div id="app">
<blog-post
v-for="post in posts"
v-bind:key="post.id"
v-bind:title="post.title"
></blog-post>
</div>
// 2
Vue.component('blog-post', {
props: ['title'],
template: '<h3>{{ title }}</h3>'
})
// 3
new Vue({
el: '#app',
data: {
posts: [
{ id: 1, title: 'My journey with Vue' },
{ id: 2, title: 'Blogging with Vue' },
{ id: 3, title: 'Why Vue is so fun' }
]
}
});
// 해당데이터를 살펴보자면, 3번의 data, posts 에 들어있는 데이터를 1번의 v-for에서
// post에담아서 꺼낸다. 해당 데이터들을 2번의 title에 꺼내진 데이터를 하나씩 입력해서 출력시킨다
props 구조
props: {
// userName: String,
// 아래와 같이 default값을 지정할 수 있다.
userName: {
type: String,
default: "I'm default"
},
},
// 위 방식 처럼타입만 설정하거나, default 설정도 가능하다
props 선호 사용법
Vue.component('blog-post', {
props: ['post'],
template: `
<div class="blog-post">
<h3>{{ post.title }}</h3>
<div v-html="post.content"></div>
</div>
`
})
new Vue({
el: '#app',
data: {
posts: [
{ id: 1, title: 'My journey with Vue', content: '1st' },
{ id: 2, title: 'Blogging with Vue', content: '2nd' },
{ id: 3, title: 'Why Vue is so fun', content: '3th' }
]
}
});
// 위 방식 처럼, props에 데이터를 넘길 때는 한 객체에 데이터를 담아 보내는것이 효율적이다
5. $emit이란?
new Vue({
el: '#app',
data: {
posts: [
{ id: 1, title: 'My journey with Vue', content: '1st' },
{ id: 2, title: 'Blogging with Vue', content: '2nd' },
{ id: 3, title: 'Why Vue is so fun', content: '3th' }
],
postFontSize: 1
}
});
부모 컴포넌트는 위의 예제와 같이 작성 될 수 있습니다. postFontSize로 텍스트의 크기가 정의 됩니다.
Vue.component('blog-post', {
props: ['post'],
template: `
<div class="blog-post">
<h3>{{ post.title }}</h3>
<button @click="$emit('enlarge-text')">Enlarge text</button>
<div v-html="post.content"></div>
</div>
`
})
<blog-post
v-for="post in posts"
v-bind:key="post.id"
v-bind:post="post"
@enlarge-text="postFontSize += 0.1"
></blog-post>
위의 컴포넌트를 보면 $emit 버튼을 클릭시 @enlarge-text="postFontSize += 0.1이 작동하는 것을 알 수 있다
또한 해당 postFontSize는등록된 데이터로 0.1씩 늘어날 것이다
위형태와 같이 부모컴포넌트로 데이터를 전달 할 수 있다
전달 받은 값은 $event를 통해서 데이터를 꺼내어 사용 가능합니다
<button @click="$emit('enlarge-text', 0.1)">Enlarge text</button>
<blog-post
v-for="post in posts"
v-bind:key="post.id"
v-bind:post="post"
@enlarge-text="postFontSize += $event"
></blog-post>
// 위방식을 아래와 같이 수정 가능
<button @click="$emit('enlarge-text', 0.1)">Enlarge text</button>
<blog-post
v-for="post in posts"
v-bind:key="post.id"
v-bind:post="post"
@enlarge-text="onEnlargeText"
></blog-post>
methods: {
onEnlargeText: function (enlargeAmount) {
this.postFontSize += enlargeAmount
}
}
6. 컴포넌트에서 v-model 사용하기
<input v-model="searchText">input 태그에서 v-model을 위의 코드와 같이 사용할 경우,
<input
v-bind:value="searchText"
v-on:input="searchText = $event.target.value">
// 위 코드는 동일한 역활을 합니다
해당 코드를 컴포넌트에서 사용하게 될 경우
<custom-input
v-bind:value="searchText"
v-on:input="searchText = $event"
></custom-input>
// value는 cutom-inpu의 props의 value와 바인딩 됩니다
// input 이벤트는 custom-input에서 $emit으로 호출되는 이벤트 입니다
Vue.component('custom-input', {
props: ['value'],
template: `
<input
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
`
})
// 위 코드를 참고하면 이해하기 편합니다
<custom-input v-model="searchText"></custom-input>
// 결론적으로 위처음사용할수 있습니다
7. slot 사용하기
컴포넌트를 사용할 때, HTML 엘리먼트와 같이 컴포넌트에 컨텐츠를 전달해야할 때가 있고 그럴 때 사용하는 것이 slot 이다
<alert-box>
Something bad happened.
</alert-box>
Vue.component('alert-box', {
template: `
<div class="demo-alert-box">
<strong>Error!</strong>
<slot></slot>
</div>
`
})
// 결과문 -> Error! Something bad happened
아래와 같이 [ Something bad happened ] 앞에 <strong>Error!</strong> 뒤에 <slot></slot>가 있기에 해당 결과가 나오게 된다
8. 동적 컴포넌트
<!-- Component changes when currentTabComponent changes -->
<component v-bind:is="currentTabComponent"></component>
동적 컴포넌트를 사용해야 할 때가 있습니다. 그럴 때 사용하는 것이 <component>와 is 입니다
9. provide와 inject
컴포넌트 사이의 계층이 많아서 props의 사용이 불편할 때
부모객체에서 provide를 사용하여 제공하며, inject을 통해 자식객체에서 주입받아 사용할 수 있다
'Vue' 카테고리의 다른 글
Vue 기본 문법 정리 (1) | 2025.01.20 |
---|---|
Vue 란? (Vue / React 차이점) (0) | 2025.01.20 |