ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 04. 뷰 컴포넌트(Component)
    FrontEnd/Vue.js 2021. 9. 10. 16:00
    반응형

    1. 뷰 컴포넌트(Comonent)

      컴포넌트(Component)란 조합하여 화면을 구성할 수 있는 블록을 의미합니다.

    좌 : 웹 페이지 한 화면의 영역을 역할별로 분할, 우 : 각각 분할된 영역 간의 관계도

    2. 컴포넌트 등록

    /* 1) 전역 컴포넌트 : 여러 인스턴스에서 공통으로 사용
    Vue.component('컴포넌트 이름', {
      // 컴포넌트 내용 : template, data, methods 등 인스턴스 옵션 속성 정의
    });
    */
    
    <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>
    /* 2) 지역 컴포넌트 : 인스턴스에 components 속성 추가
    new Vue({
      components: {
        '컴포넌트 이름': 컴포넌트 내용
      }
    });
    */
    
    <html>
      <head>
        <title>Vue Component Registration</title>
      </head>
      <body>
        <div id="app">
          <button>컴포넌트 등록</button>
          <my-local-component></my-local-component>
        </div>
    
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
        <script>
          var cmp = {
            // 컴포넌트 내용
            template: '<div>지역 컴포넌트가 등록되었습니다!</div>'
          };
    
          new Vue({
            el: '#app',
            components: {
              'my-local-component': cmp
            }
          });
        </script>
      </body>
    </html>

      > 전역 컴포넌트는 한 번 등록하면 어느 인스턴스에서든 사용이 가능하나, 지역 컴포넌트는 새 인스턴스를 생성할 때마다 등록해줘야 합니다.

     

    3. 뷰 컴포넌트 통신

      뷰 프레임워크는 내부적으로 각 컴포넌트의 유효 범위를 독립적으로 정의했기에 다른 컴포넌트의 값을 직접 참조할 수 없습니다.

    상위 - 하위 컴포넌트 간 통신 방식

      1) 상위에서 하위 컴포넌트로 데이터 전달하기 : props

    /*
    [하위 컴포넌트의 props 속성 정의 방식]
    Vue.component('child-component', {
      props: ['props 속성 이름'],
    });
    
    [상위 컴포넌트의 HTML 코드]
    <child-component v-bind:props 속성 이름="상위 컴포넌트 data 속성"></child-component>
    */
    
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Vue Props Sample</title>
      </head>
      <body>
        <div id="app">
          <!-- 3. HTML에 컴포넌트 태그 추가
               Tip) 오른쪽에서 왼쪽으로 속성을 읽으면 더 수월합니다. -->
          <child-component v-bind:propsdata="message"></child-component>
        </div>
    
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
        <script>
          Vue.component('child-component', { // 2. 하위 컴포넌트 등록
            props: ['propsdata'],
            template: '<p>{{ propsdata }}</p>',// 4. Hello Vue! passed from Parent Component
          });
    
          new Vue({ // 1. 인스턴스 생성
            el: '#app',
            data: {
              message: 'Hello Vue! passed from Parent Component'
            }
          });
        </script>
      </body>
    </html>

      2) 하위에서 상위 컴포넌트로 이벤트 전달 :  emit

    /*
    [이벤트 발생]
    this.$emit('이벤트명');
    this.$emit('이벤트 이름', 인자1, 인2, ...)
    > 하위 컴포넌트의 특정 데이터를 전달할 수 있습니다. 
      단, 전달받은 인자 값은 상위 컴포넌트에서 참고용으로만 활용, 데이터 값은 변경하지 말아야 합니다.
    
    [이벤트 수신]
    <child-component v-on:이벤트명="상위 컴포넌트 메서드명"></child-component>
    */
    
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Vue Event Emit Sample</title>
      </head>
      <body>
        <div id="app">
          <child-component v-on:show-log="printText"></child-component> // 3. 이벤트 수신
        </div>
    
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
        <script>
          Vue.component('child-component', {
            template: '<button v-on:click="showLog">show</button>', // 1. 버튼 등록
            methods: {
              showLog: function() {
                this.$emit('show-log'); // 2. 하위 컴포넌트 이벤트 발생
              }
            }
          });
    
          new Vue({
            el: '#app',
            data: {
              message: 'Hello Vue! passed from Parent Component'
            },
            methods: {
              printText: function() { // 4. 메서드 수행
                console.log("received an event");
              }
            }
          });
        </script>
      </body>
    </html>

      3) 이벤트 버스(Event Bus) : 상위 - 하위 관계를 유지하고 있지 않아도 데이터를 한 컴포넌트에서 다른 컴포넌트로 전달할 수 있는 방법입니다.

    /*
      1. 이벤트 버스를 위한 추가 인스턴스 1개 생성
      2. 이벤트를 보내는 컴포넌트
      3. 이벤트를 받는 컴포넌트
    */
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Vue Event Bus Sample</title>
      </head>
      <body>
        <div id="app">
          <child-component></child-component>
        </div>
    
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
        <script>
          var eventBus = new Vue(); // 1. 이벤트 버스를 위한 추가 인스턴스 1개 생성
    
          Vue.component('child-component', {
            template: '<div>하위 컴포넌트 영역입니다.<button v-on:click="showLog">show</button></div>',
            methods: {
              showLog: function() {
                eventBus.$emit('triggerEventBus', 100); // 2. 이벤트를 보내는 컴포넌트
              }
            }
          });
    
          var app = new Vue({
            el: '#app',
            created: function() {
              eventBus.$on('triggerEventBus', function(value){ // 3. 이벤트를 받는 컴포넌트
                console.log("이벤트를 전달 받음. 전달 받은 값 : ", value);
              });
            }
          });
        </script>
      </body>
    </html>

      > 이벤트 버스를 활용하면 직접적으로 데이터를 전달할 수 있어 편리하나 컴포넌트가 많아질 경우 유지보수가 어렵습니다. 이 문제를 해결하기 위해서는 뷰엑스(Vuex)라는 상태 관리 도구가 필요합니다.

     

    반응형

    'FrontEnd > Vue.js' 카테고리의 다른 글

    06. 액시오스(Axios)  (0) 2021.09.11
    05. 뷰 라우터(Router)  (0) 2021.09.11
    03. 뷰 인스턴스(Instance)  (0) 2021.09.07
    02. 개발환경 설정  (0) 2021.09.07
    01. Vue.js  (0) 2021.09.07

    댓글

Designed by Tistory.