반응형

이번 포스팅은 뷰 컴포넌트에 대하여 알아보도록 하겠습니다.

 

#1. 컴포넌트


컴포넌트(Component)란 조합하여 화면을 구성할 수 있는 블록(화면의 특정 영역)을 의미합니다. 컴포넌트를 활용하면 화면을 빠르게 구조화하여 일괄적인 패턴으로 개발할 수 있습니다. 이렇게 화면의 영역을 컴포넌트로 쪼개서 재활용할 수 있는 형태로 관리하면 나중에 코드를 다시 사용하기가 훨씬 편리합니다. 또한 모든 사람들이 정해진 방식대로 컴포넌트를 등록하거나 사용하게 되므로 남이 작성한 코드를 직관적으로 이해할 수 있습니다.

뷰에서는 웹 화면을 구성할 때 흔히 사용하는 내비게이션 바(Navigation bar), 테이블(Table), 리스트(List), 인풋 박스(Inout box) 등과 같은 화면 구성 요소들을 잘게 쪼개어 컴포넌트로 관리합니다. 다음 그림에서 왼쪽은 웹 페이지 한 화면의 영역을 각각 역할별로 분할한 그림이고, 오른쪽은 각각 분할된 영역 간의 관계를 도식화한 그림입니다. 여기서 각각 분할된 영역은 컴포넌트를 의미합니다.

위의 왼쪽 그림은 화면 전체를 Header, Content, Footer로 분할하였고, Content 영역을 Aside, List 영역으로 분할하였습니다. 이는 화면 전체를 3개의 컴포넌트로 분할한 후 분할된 1개의 컴포넌트에서 다시 2개의 하위 컴포넌트로 분할한 것입니다. 그리고 오른쪽 그림은 각 컴포넌트 간의 관계를 나타냅니다. 이러한 컴포넌트 간의 관계는 뷰에서 화면을 구성하는 데 매우 중요한 역할을 하며, 웹 페이지 화면을 설계할 때도 이와 같은 골격을 유지하면서 설계를 해야 합니다. 참고로 컴포넌트 간의 관계는 자료구조의 트리(Tree) 모양과 유사합니다.

 

#2. 컴포넌트 등록하기


컴포넌트를 등록하는 방법은 전역과 지역의 두 가지가 있습니다. 지역(Local) 컴포넌트는 특정 인스턴스에서만 유효한 범위를 갖고, 전역(Global) 컴포넌트는 여러 인스턴스에서 공통으로 사용할 수 있습니다. 더 쉽게 말하자면 지역은 특정 범위 내에서만 사용할 수 있고, 전역은 뷰로 접근 가능한 모든 범위에서 사용할 수 있다는 거죠. 그럼 두 가지 방법에 대해 살펴보겠습니다.

전역(Global) 컴포넌트 등록하기

전역 컴포넌트는 뷰 라이브러리를 로딩하고 나면 접근 가능한 Vue 변수를 이용하여 등록합니다. 전역 컴포넌트를 모든 인스턴스에 등록하려면 Vue 생성자에서 .component()를 호출하여 수행하면 됩니다. 형식은 아래와 같습니다.

Vue.component('컴포넌트 이름', {
       // 컴포넌트 내용
});

전역 컴포넌트 등록 형식에는 컴포넌트 이름과 컴포넌트 내용이 있습니다. 컴포넌트 이름은 template 속성에서 사용할 HTML 사용자 정의 태그(custom tag) 이름을 의미합니다. 태그 이름의 명명 규칙은 HTML 사용자 정의 태그 스펙에서 강제하는 '모든 소문자'와 '케밥 기법'을 따르지 않아도 됩니다.

그리고 컴포넌트 태그가 실제 화면의 HTML 요소로 변환될 때 표시될 속성들을 컴포넌트 내용에 작성합니다. 컴포넌트 내용에는 template, data, methods 등 인스턴스 옵션 속성을 정의할 수 있습니다.

▶ 사용자 정의 태그 : HTML 표준 태그들 이외에도 웹 개발자가 직접 정의하여 사용할 수 있는 태그

▶ 케밥 기법 : 변수가 단어의 조합으로 이루어져 있을 때, 단어와 단어 사이를 -로 잇는 변수 명명 방식 ex) my-component, my- global-component 등

그럼 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.jsdeliver.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>

그리고 등록된 my-component 컴포넌트는 실제로 화면에서 아래와 같이 그려집니다.

<div>전역 컴포넌트가 등록되었습니다.</div>

결론적으로 인스턴스가 생성된 후 화면에 그려질 때 실제 HTML 코드 모양은 다음과 같습니다.

   <div id="app">
       <button>컴포넌트 등록</button>
       <!-- 등록한 my-component가 최종적으로 변환된 모습-->
       <div>전역 컴포넌트가 등록되었습니다.</div>
    </div>

지역 컴포넌트 등록

지역 컴포넌트 등록은 전역 컴포넌트 등록과는 다르게 인스턴스에 component속성을 추가하고 등록할 컴포넌트 이름과 내용을 정의하면 됩니다. 지역 컴포넌트 등록 형식은 아래와 같습니다.

new Vue({
   component :
 {
       '컴포넌트 이름' : '컴포넌트 내용'
   }
});

컴포넌트 이름은 전역 컴포넌트와 마찬가지로 HTML에 등록할 사용자 정의 태그를 의미하고, 컴포넌트 내용은 컴포넌트 태그가 실제 화면 요소로 변환될 때의 내용을 의미합니다.

그럼 지역 컴포넌트를 등록하는 방법을 다음 예제를 통해 살펴보겠습니다.

<script>
   var cmp = {
      // 컴포넌트 내용
      template : '<div>지역 컴포넌트가 등록되었습니다.</div>'
   };

   new Vue ({
      el : '#app',
      component : {
           'my-local-component' : cmp  
      }
   });
</script>

변수 cmp에는 홤ㄴ에 나타낼 컴포넌트의 내용을 정의했습니다. 컴포넌트의 내용에 template, data, methods 등 여러 가지 속성이 들어갈 수 있지만 여기서는 간단히 컴포넌트를 등록하는 코드만 보여주기 위해 template 속성만 사용하였습니다. 그리고 template 속성에 <div> 태그 1개만 설정합니다. 아래 뷰 인스턴스에 component 속성을 추가하고 컴포넌트 이름에는 my-local-component를, 컴포넌트 내용에는 앞에서 컴포넌트 내용을 정의한 변수 cmp를 지정합니다.

그리고 HTML에 <my-local-component> 태그를 추가하여 컴포넌트를 화면에 나타냅니다.

   <div id="app">
       <button>컴포넌트 등록</button>
       <my-local-component> </my-local-component>
    </div>

이 예제를 실행하면 아래와 같은 결과 화면이 나타납니다.

  
   지역 컴포넌트가 등록되었습니다.    

지금까지 지역 컴포넌트 등록과 전역 컴포넌트 등록에 대하여 알아보았습니다. 그런데 아직 웹 페이지 상에서 드러나는 결과만으로는 전역 컴포넌트와 지역 컴포넌트의 차이점을 찾기가 어렵습니다. 앞에서 배운 인스턴스 유효 범위를 이용해서 전역 컴포넌트, 지역 컴포넌트 간에는 어떤 차이점이 있는지 살펴보겠습니다.

#3. 지역 컴포넌트와 전역 컴포넌트의 차이


지역 컴포넌트와 전역 컴포넌트의 차이점을 이해하기 위해서는 앞에서 배운 인스턴스의 유효 범위를 이해해야 합니다. 인스턴스의 유효 범위란 HTML의 특정 범위 안에서만 인스턴스의 내용이 유효한 것이라고 했는데, 그럼 다음 코드를 살펴보겠습니다.

   <div id="app">
       <h3>첫 번째 인스턴스 영역</h3>
       <my-global-component> </my-global-component>   -------------- 전역 컴포넌트           
       <my-local-component> </my-local-component>        -------------- 지역 컴포넌트
   </div>

    <script>
        // 전역 컴포넌트 등록
        Vue.component('my-global-component' , {
             template : '<div>전역 컴포넌트입니다.</div>'
         });
        // 지역 컴포넌트 내용
        var cmp = {
             template : '<div>지역 컴포넌트입니다.</div>'
         });
        // 뷰 인스턴스 생성
        new Vue ({
           el : '#app',
           // 지역 컴포넌트 등록
           component : {
               'my-local-component' : cmp
           }
        });
    </script>     

위 코드는 인스턴스를 하나 생성하여 my-global-component 전역 컴포넌트와 my-local-component 지역 컴포넌트를 등록하고 화면에 나타내는 예제입니다. 코드를 실행하면 아래와 같은 결과 화면이 나타납니다.

첫 번째 인스턴스 영역


전역 컴포넌트입니다.
지역 컴포넌트 입니다.

여기까지 앞에서 배운 내용으로 충분히 이해할 수 있을 겁니다. 그럼 이번에는 인스턴스를 하나 더 생성하고 해당 인스턴스에서 지역, 전역 컴포넌트를 모두 표시해 보겠습니다.

  <div id="app">
       <h3>첫 번째 인스턴스 영역</h3>
       <my-global-component> </my-global-component>   -------------- 전역 컴포넌트           
       <my-local-component> </my-local-component>        -------------- 지역 컴포넌트
  </div>
  <hr>
  </div id="app2">
       <h3>두 번째 인스턴스 영역</h3>
       <my-global-component> </my-global-component>   -------------- 전역 컴포넌트           
       <my-local-component> </my-local-component>        -------------- 지역 컴포넌트
  </div>
  
  
    <script>
        // 전역 컴포넌트 등록
        Vue.component('my-global-component' , {
             template : '<div>전역 컴포넌트입니다.</div>'
         });
        // 지역 컴포넌트 내용
        var cmp = {
             template : '<div>지역 컴포넌트입니다.</div>'
         });
        // 첫번째 인스턴스 생성
        new Vue ({
           el : '#app',
           // 지역 컴포넌트 등록
           component : {
               'my-local-component' : cmp
           }
        });
         // 두번째 인스턴스 생성
        new Vue ({
           el : '#app2'
        });
    </script>     

HTML에 <div id="app2"> 태그를 하나 더 추가하고, 인스턴스도 하나 더 추가하였습니다. 그리고 <div id="app2"> 태그에 전역, 지역 컴포넌트를 모두 등록하였습니다. 첫 번째 인스턴스 영역과 두 번째 인스턴스 영역을 구분하기 위해 구분선으로는 <hr> 태그를 사용하였습니다.

첫 번째 인스턴스 영역


전역 컴포넌트입니다.
지역 컴포넌트 입니다.

두 번째 인스턴스 영역


첫 번째

인스턴스 영역에는 전역, 지역 컴포넌트가 모두 정상적으로 나타났습니다. 하지만 구분선 밑에 두 번째 인스턴스 영역에는 전역 컴포넌트만 나타나고, 지역 컴포넌트는 나타나지 않았습니다. 왜 그럴까요? 전역 컴포넌트와 지역 컴포넌트의 유효 범위가 다르기 때문입니다.

전역 컴포넌트는 인스턴스를 새로 생성할 때마다 인스턴스에 component 속성으로 등록할 필요없이 한 번 등록하면 어느 인스턴스에서든지 사용할 수 있습니다. 반대로 지역 컴포넌트는 새 인스턴스를 생성할 때마다 등록해 줘야 합니다.

첫 번째 인스턴스의 유효 범위는 첫 번째 인스턴스 영역으로 제한되기 때문에 <div id="app">에 지역 컴포넌트를 등록했어도 두 번째 인스턴스 영역인 <div id="app2">의 범위 안에서는 지역 컴포넌트가 인식되지 않아 위와 같은 결과를 나타냅니다.

<my-local-component> 태그는 두 번째 인스턴스의 유효 범이 안에 있더라도 이 컴포넌트가 등록된 첫 번째 유효 범위를 벗어나기 때문에 브라우저에서는 HTML 사용자 정의 태그로 인식하고, 뷰에서는 해당 컴포넌트를 제대로 등록했는지 물어보는 오류를 표시합니다.

 

Reference

1. 장기효 [예제로 이해하고 실전 프로젝트로 완성한다! Vue.js 입문]

반응형

'Development > Web' 카테고리의 다른 글

[Web] 크로스 도메인  (0) 2022.09.23
[Web] 뷰 컴포넌트 통신  (0) 2022.09.19
[Web] 뷰 인스턴스 라이프 사이클  (0) 2022.09.18
[Web] 뷰 인스턴스  (0) 2022.09.18
[Web] JSP에서 엑셀 파일로 저장하기  (0) 2020.04.08

+ Recent posts