컴포넌트(Component)란 조합하여 화면을 구성할 수 있는 블록을 의마합니다. 컴포넌트를 활용하면 화면을 빠르게 구조화하여 일괄적인 패턴으로 개발 할 수 있으며, 코드를 쉽게 이해하고 재사용할 수 있습니다.
컴포넌트는 Vue의 가장 강력한 기능 중 하나입니다. 기본 HTML
엘리먼트를 확장하여 재사용 가능한 코드를 캡슐화하는 데 도움이 됩니다. 상위 수준에서 컴포넌트는 Vue의 컴파일러에 의해 동작이 추가된 사용자 지정 엘리먼트입니다. 경우에 따라 특별한 is
속성으로 확장 된 원시 HTML
엘리먼트로 나타낼 수도 있습니다.
Vue 컴포넌트는 Vue인스턴스이기도 합니다. 그러므로 모든 옵션 객체를 사용할 수 있습니다. 그리고 같은 라이프사이클 훅을 사용할 수 있습니다.
컴포넌트를 등록하는 방법은 전역(Global)과 지역(Local)의 두 가지의 방법이 있습니다. 지역 컴포넌트는 특정 인스턴스에서만 유효하고, 전역 컴포넌트는 모든 범위의 여러 인스턴스에서 공통으로 사용할 수 있습니다.
전역 컴포넌트는 뷰 라이브러리를 로딩하고 나면 접근 가능한 Vue 변수를 이용하여 등록합니다. 전역 컴포넌트를 모든 인스턴스에 등록하려면 아래와 같은 형식으로 Vue 생성자에서 .component()
를 호출하여 수행하면 됩니다.
<!-- 전역 컴포넌트 등록 형식 -->
Vue.component('컴포넌트 이름', {
// 컴포넌트 내용
});
컴포넌트 이름은 template
속성에서 사용할 HTML
사용자 정의 태그(HTML 표준 태그들 이외에도 개발자가 직접 정의하여 사용할 수 있는 태그)이름을 의미 합니다.
컴포넌트 내용에는 컴포넌트 태그가 실제 화면의 HTML 요소로 변환될 때 표시될 속성들을 작성하며, template
, data
, methods
등 인스턴스 옵션 속성을 정의할 수 있습니다.
Vue.component()
로 전역 컴포넌트 1개를 등록하고 화면에 그리는 예제는 아래와 같습니다.
<html>
<head>
<title>Vue Component Registration</title>
</head>
<body>
<div id="app>
<button>컴포넌트 등록</button>
<my-component></my-component>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
<script>
Vue.component('my-component', {
template: '<div>전역 컴포넌트가 등록되었습니다.</div>'
});
new Vue({
el: '#app'
});
</script>
</body>
</html>
위 예제와 같이 전역 컴포넌트를 등록하려면 HTML 에서 사용할 태그 이름을 컴포넌트 이름으로 작성하고, 중괄호 {}
안에는 HTML 태그가 실제로 화면에서 그려질 때 표시될 내용을 작성해야 합니다. 이 예제에서는 컴포넌트 이름을 my-component
로 지정했고, 컴포넌트 내용으로는 template
속성을 정의하고 '전역 컴포넌트가 등록되었습니다' 라는 텍스트를 포함한 <div>
태그를 작성했습니다.
따라서 이 컴포넌트를 아래와 같이 HTML 에 추가하면 최종적으로 컴포넌트가 등록됩니다.
// 컴포넌트 추가 됨
<my-component></my-component>
// 실제로 화면에 그려진 내용
<div>전역 컴포넌트가 등록되었습니다.</div>
지역 컴포넌트 등록은 전역 컴포넌트 등록과는 다르게 인스턴스에 components
속성을 추가하고 등록할 컴포넌트 이름과 내용을 정의하면 됩니다. 등록 형식은 아래와 같습니다.
<!-- 지역 컴포넌트 등록 형식 -->
new Vue({
components: {
'컴포넌트 이름': 컴포넌트 내용
}
});
컴포넌트 이름은 전역 컴포넌트와 마찬가지로 HTML에 등록할 사용자 정의 태그를 의마하고, 컴포넌트 내용은 컴포넌트 태그가 실제로 화면 요소로 변환될 내용을 의미합니다.
다음 예제는 지역 컴포넌트를 등록하는 방법입니다.
<script>
var cmp = {
// 컴포넌트 내용
template: '<div>지역 컴포넌트가 등록되었습니다.</div>'
};
new Vue({
el: '#app',
components: {
'my-local-component': cmp
}
});
</script>
변수 cmp에는 화면에 나타낼 컴포넌트 내용을 정의했습니다. 컴포넌트 내용에 template
, data
, method
등 여러가지 속성이 들어갈 수 있지만 여기서는 간단히 template
속성만 정의하고, 앞에서 컴포넌트 내용을 정의한 변수 cmp
를 지정했습니다.
그리고 HTML에 <my-local-component>
태그를 추가하여 컴포넌트를 화면에 나타냅니다.
<div id="app">
<button>컴포넌트 등록</button>
<my-local-component></my-local-component>
</div>
컴포넌트 간에 데이터를 주고받을 때 단방향 바인딩과 양방향 바인딩 방식이 어떻게 다르고, 어떤 장단점을 가지고 있나요?
단방향 바인딩의 경우 Javascript 데이터에 연결된 변수를 바꿈에 따라 우리가 보여주는 변수가 변경되는 것을 단방향 바인딩이라고 합니다. 단방향 바인딩에 경우 데이터가 한 방향으로만 흐르기 때문에 하위 컴포넌트가 부모의 상태를 변경하는 것이 다른 특별한 조치가 없고는 불가능합니다.
따라서 데이터의 흐름을 파악하기에는 더 나은 방법일 수 있습니다. 하지만 컴포넌트 가 데이터 전달에 있어서 항상 로직이 들어가야한다는 단점이 있습니다. 이는 곧, Vue.js 의 데이터가 DOM으로 전달되게 되며, 데이터 값이 변경되면 자동으로 업데이트 될 수 있습니다.
양방향 데이터 바인딩은 Vue 인스턴스와 component가 서로의 데이터에 접근하는 것을 말합니다. 즉, DOM과 자바스크립트를 일치 시켜준다는 것을 의미합니다. 이는 인스턴스가 템플릿의 값을 변경시킬 수 있다는 의미가 됩니다. 예를 들면, 어떤 Form에 값을 입력하게 되면 DOM과 자바스크립트가 동시에 변경된다는 것입니다.
양방향 데이터 바인딩은 데이터 변경이 일정하지 않기 때문에 데이터의 흐름을 알기에 어려울 수 있습니다. 이는 곧 디버깅 시 어려움이 있을 수 있고, 변경되는 데이터의 감지를 위해 추가적인 작업이 들어가게 되고 곧 성능이슈가 발생할 수 있습니다.
vue 에서는 v-model
디렉티브를 이용하여 양방향 데이터 바인딩을 지원합니다.