컴포넌트는 유용하다.
여러 개의 li를 생성할 때, 페이지의 다른 부분에서 재사용할 수 있다.
컴포넌트는 큰 애플리케이션을 작은 청크 여러 개로 분할할 때에도 유용하다.
그렇다면, 컴포넌트는 어떻게 생성할까? 그리고 작동원리는 뭘까?
# 컴포넌트 생성방법
컴포넌트는 Vue.js가 인식하는 공식 기능이다.
컴포넌트는 Vue 앱에서 생성할 수 있다.
createApp을 사용해 Vue 앱을 생성하고, 그 생성된 Vue 앱을 이용해서 컴포넌트를 만든다.
Vue 앱을 저장하는 app 상수에서 component 메서드를 호출한다.
Vue에 새 컴포넌트를 생성하고 싶다고 알려주는 것.
**참고로 app.mount('#app')이 app.component 뒤에 와야한다.
app.component();
## component 메서드
component 메서드는 두 개의 인수를 갖는다.
1/ 첫번 째는 '식별자'.
컴포넌트는 기본적으로 커스텀 HTML 요소이다.
커스텀 HTML 태그를 정의해야하는데, 예를 들면 'user-contact'나 'friend-contact'와 같이 정의해볼 수 있다.
항상 대시(-) 기호를 포함한 식별자를 사용해야한다. 즉, 컴포넌트의 이름(커스텀 HTML태그)은 대시 기호를 포함한 두 단어로 구성되어야 한다.
그 이유는, 공식 내장 HTML 요소와의 충돌을 피하기 위해.
예를 들어, 컴포넌트 이름을 h2로 지정하면 이미 h2 요소가 존재하므로 충돌이 발생한다.
app.component('h2');
'friend-contact'를 컴포넌트의 식별자로 해보자.
2/ 두 번째는 '구성객체'.
component 메서드에 전달할 두 번째 인수는 createApp에 전달한 것과 같은 구성객체.
Vue 컴포넌트는 본질적으로 Vue 앱과 같다. 다른 앱에 속한 앱일 뿐이다.
즉, 여기서 생성한 컴포넌트는 새로운 Vue 앱이다. 하지만, 중요한 건 메인 앱과 연결될 앱이라는 것.
즉, 컴포넌트는 미니 Vue앱인 셈이다. 따라서 data, methods가 있는 구성 객체를 가질 수 있다.
app.component('friend-contact', {})
컴포넌트에 커스텀 data, methods를 설정해보자.
컴포넌트 전용 methods를 통해 컴포넌트 전용 data를 변경하는 것.
참고로, 컴포넌트는 캡슐화가 되어 있어 메인 앱에 동일한 data, method가 있어도 충돌이 발생하지 않는다. 즉, 부모앱과 통신하지 않는다.
아래와 같이, friend-contact라는 컴포넌트를 생성했다.
app.component('friend-contact', {
data(){
return { detailsAreVisible: false }
},
methods: {
this.detailsAreVisible = !this.detailsAreVisible;
}
})
# 컴포넌트 사용 방법
생성한 이 컴포넌트를 어떻게 사용할까? 그리고 어떤 식으로 작동할까?
컴포넌트를 사용하기 전에 한가지 중요한 점이 빠져있다. → template!
새로운 앱이므로 자체 template이 필요하다.
메인 앱에는 template이 있다. 앱을 마운트한 전체 <section id="app"></section>이 template.
컴포넌트는 미니앱이다. 따라서 자체 템플릿을 설정해야한다.
여기서는 컴포넌트를 mount하거나 app.mount 이렇게 mount를 호출하지 않는다.
대신, 구성객체 옵션에 template 옵션을 추가해보자.
template 옵션을 사용하면 해당 앱의 template(HTML 코드)을 정의할 수 있다.
여러 줄의 문자열을 작성하기 위해 백틱을 사용해보자. 그리고 HTML 코드에서 li항목을 가져온다.
즉, Vue 기능들이 포함된 JavaScript 문자열이 된다.
template에서 v-for를 제거하고, 컴포넌트의 data에 friend 프로퍼티를 추가해보자. (임시로 사용하는 data)
app.component("friend-contact", {
template: `
<li>
<h2>{{ friend.name }}</h2>
<button @click="toggleDetails()">
{{ detailsAreVisible ? 'Hide' : 'Show'}} Details
</button>
<ul v-if="detailsAreVisible">
<li><strong>Phone:</strong> {{ friend.phone }}</li>
<li><strong>Email:</strong> {{ friend.email }}</li>
</ul>
</li>
`,
data() {
return {
detailsAreVisible: false,
friend: {
id: "manuel",
name: "Manuel Lorenz",
phone: "01234 5678 991",
email: "manuel@localhost.com",
},
};
},
methods: {
toggleDetails() {
this.detailsAreVisible = !this.detailsAreVisible;
},
},
});
위와 같이 저장하면 마침내 커스텀 컴포넌트, 즉 커스텀 HTML 요소를 사용할 수 있게 된다.
이제 메인앱에서 friend-contact를 공식 HTML 요소인것 처럼 사용할 수 있다. (진짜 HTML 요소는 아니다.)
<friend-contact></friend-contact> <!--브라우저가 인식 불가-->
<section id='app'>
<ul>
<friend-contact></friend-contact> <!--커스텀 HTML 요소-->
</ul>
<h2></h2>
이 커스텀 HTML요소는 브라우저가 인식할 수 있는 HTML 요소가 아니다.
Vue앱이 제어하는 부분 밖에서 사용을 시도할 경우, 아무 일도 일어나지 않고 브라우저가 무시한다.
하지만 메인 앱에 등록한 컴포넌트이므로 메인 앱 내부에서는 Vue가 이 컴포넌트를 인식한다.
component 메서드를 사용해 첫번 째 인수에 전달한 식별자를 현재 HTML에 그대로 사용하고 있다.
그래서 기본 HTML 태그 이름을 사용하면 안되는 이유!
만약 컴포넌트 이름을 'h2'로 지정했다면, Vue는 이것을 커스텀 컴포넌트로 인식하지 않는다.
지금은 컴포넌트 식별자에 대시기호가 포함되어 있고, 두 단어로 구성되어있다. Vue는 index.html에 있는 식별자를 감지하고, template을 포함한 미니앱과 이 template 안에 있는 모든 동적 코드를 렌더링한다.
다시 저장하고 새로고침하면 화면에 잘 뜬다.
컴포넌트가 서로 완전히 분리되어 독립적으로 작동한다.
그래서 'Show Details'와 'Hide Details'도 각각 잘 작동한다.
컴포넌트를 활용하면 HTML 코드를 쉽게 복제하고 캡슐화할 수 있다.
data와 methods로 캡슐화 한다.
따라서 컴포넌트는 연결된 data와 methods을 포함한 재사용 가능한 HTML 코드라고 할 수 있다.
컴포넌트는 원하는만큼 얼마든지 추가할 수 있다. 모두 렌더링되고, 독립적으로 작동한다.
이제 하나의 메인 앱에 여러 개의 Vue 미니 앱을 생성할 수 있다.
이 앱들은 정보를 공유하기 위해 서로 통신할 수 있으니 일거양득이다.
코드가 캡슐화되고 분리되기때문에 프로젝트규모가 큰 경우 코드 작업이 훨씬 수월해진다. 동시에 분리된 모든 코드를 결합해 보다 큰 앱을 만들어낼 수도 있다.
** 출처: 모든 내용은 Udemy Vue-완벽가이드 강의를 기반으로 작성하였습니다.
'Vue.js' 카테고리의 다른 글
[Udemy Vue 완벽가이드 Section6] 73. 여러 Vue앱과 여러 컴포넌트 (0) | 2023.08.17 |
---|---|
[Udemy Vue 완벽가이드 Section6] 72. 복잡한 사용자 인터페이스 구축에 컴포넌트를 사용하는 이유 (0) | 2023.08.17 |
[Udemy Vue 완벽가이드 Section6] 70. 문제 이해하기 (0) | 2023.08.17 |
[Udemy Vue 완벽가이드 Section5] 66. Vue 앱 생명주기 - 이론, 실습 (0) | 2023.08.16 |
[Udemy Vue 완벽가이드 Section5] 64. Ref 활용하기 (0) | 2023.08.15 |