티스토리 뷰

Vue

Vue - Component

김관장 2022. 6. 3. 18:05

1. Vue  - Component ?

  • 컴포넌트는 화면의 영역을 구분하여 개발할 수 있는 뷰의 기능입니다. 컴포넌트 기반으로 화면을 개발하게 되면 코드의 재사용성이 올라가고, 화면 빠르게 구조화하여 일괄적인 패턴으로 개발 할 수 있습니다.
  • 기본 HTML 엘리먼트를 확장하여 재사용 가능한 코드를 캡슐화하는데 도움이 되며, 상위 수준의 컴포넌트는 Vue의 컴파일러에 의해 동작이 추가된 사용자 지정 엘리먼트입니다.
  • Vue 컴포넌트는 Vue 인스턴스이기 때문에 모든 옵션 객체를 사용할 수 있으며, 같은 라이프사이클 훅을 사용할 수 있습니다.

2. 컴포넌트 등록 방법 2가지 (전역, 지역)

   2-1. 전역 컴포넌트

<!-- 1. 전역 컴포넌트 생성 코드 형식 방식 -->

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


<!-- 2. 전역 컴포넌트 생성 예시 -->

Vue.component('app-header', {
  template: '<h1>Header Component</h1>'
});
 
 
<!-- 3. 전역 컴포넌트 사용 예시 -->

<div id="header">
  <app-header></app-header>
</div>

<div id="body">
  <app-header></app-header>
</div>


<!-- 결과적으로 <app-header></app-header>는 <h1>Header Component</h1> 와 같이 표시됩니다. -->
  • 전역 컴포넌트는 Vue 생성자에서 .component()를 호출하여 등록합니다.
  • 컴포넌트 이름'은 template 속성이 보여질 HTML 사용자 정의 태그의 명을 말합니다.
  • '컴포넌트 내용'에는 실제 화면의 HTML 요소로 변활될 때 표시될 속성들을 작성하며 ( template, data, methods )등 과 같은 인스턴스 옵션 속성을 정의 할 수 있습니다.

   2-2. 지역 컴포넌트

<!-- 1. 지역 컴포넌트 등록 형식 -->

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


<!-- 2. 지역 컴포넌트 생성 예시 -->

new Vue({
     
    el: '#app', // => 'app이라는 id를 가진 테그로 가서 해당 인스턴스를 붙이겠다' 라는 의미

    components: {
        'app-footer': {
            template: '<footer>footer !!</footer>'
        }
    }

});
        

<!-- 3. 지역 컴포넌트 사용 예시 -->

<div id="app">
     <app-footer></app-footer>
</div>


<!-- 결과적으로 <app-footer></app-footer>는 <footer>footer !!</footer> 와 같이 표시됩니다. -->
  • 지역 컴포넌트는 인스턴스에 components 속성을 추가하고 등록할 컴포넌트 이름, 내용을 정의합니다.
  • 컴포넌트 이름과 내용은 전역 컴포넌트와 같은 기능입니다.

   2-3. 전역 / 지역 컴포넌트의 차이점

  • 전역 컴포넌트는 인스턴스를 새로 생성 할 때마다 인스턴스에 components 속성으로 등록할 필요 없이 한 번 등록하면 어느 인스턴스에서든지 사용 가능합니다.
  • 지역 컴포넌트는 새 인스턴스를 생성 할 때마다 등록을 해줘여야합니다. 

3. 컴포넌트의 통신 방식

  • 뷰 컴포넌트는 각각 고유한 데이터 유효 범위를 갖습니다.
  • 상위에서 하위로는 데이터를 내려주는 "프롭스 속성", 하위에서 상위로는 이벤트를 올려주는 "이벤트 발생" 과 같은 규칙을 따라 컴포넌트 간에 데이터를 주고 받을 수 있습니다.
  • 더 자세히 내용 및 기본적인 props, event emit 동작과 관련된 내용은 따로 정리한 글을 참고 부탁드립니다.
    https://ji-musclecode.tistory.com/43

   3-1. 같은 레벨의 컴포넌트 간 통신 방법

<body>
	
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    
    <div id="app">
        {{num}}
        <app-header v-bind:propsdata="num"></app-header>
        <app-footer v-on:pass="deliverNum"></app-footer>
    </div>

    <script>

        let appHeader = {
            template: '<div>{{propsdata}}</div>',
            props: ['propsdata']
        }

        let appFooter = {
            template: '<div> Footer <button v-on:click="passNum"> pass </button> </div>',
            methods: {
                passNum: function () {
                    this.$emit('pass', 10);
                }
            }
        }

        new Vue({
            el: '#app',
            components: {
                'app-header': appHeader,
                'app-footer': appFooter
            },
            methods: {
                deliverNum: function (num) {
                    this.num = num;
                },
            },
            data: {
                num: 0
            }
        })
    </script>
    
</body>

사진 출처 : https://jinyisland.kr/p/vue-컴포넌트에-대한-개념/

  • 위 사진에서 header, footer와 같이 같은 레벨의 컴포넌트에서 통신을 하기 위해서는 직접적으로 한번에 통신을 할 수 없고, 부모(사진 상 Root)컴포넌트를 통해 event 와 props 동작을 통해 통신할 수 있습니다.
  • 위 예제 코드의 동작 순서를 살펴보면 아래와 같습니다.

    1) app-footer에서 pass란 버튼을 클릭하면 passNum() => this.$emit('pass',10) 을 호출합니다.
    2) app-footer의 태그 선언 부분의 v-on:pass="deliverNum" 에 따라 root의 deliverNum() 함수를 호출합니다.
    3) deliverNum()함수의 호출 결과 num을 10 으로 바꿔줍니다.
    4) app-header의 태그 선언 부분의 v-bind:propsdata="num" 에 따라 app-header 컴포넌트의 propsdata 값에 num값인 10이 할당 됩니다. ( props:['propsdata'] => propsdata라는 변수를 통해 props를 받겠다는 의미 )
    6) 따라서 최종적으로 {{propsdata}}에 10이란 값이 화면에 출력된다는 것을 알 수 있습니다. ( {{}} - 템플릿 문법 )

 

 

component, props / event-emit 세 문법은 연관되어 사용하므로 잘 숙지해야겠다 !

 

 

🔗 참고한 글

 

Cracking Vue.js

 

joshua1988.github.io

 

'Vue' 카테고리의 다른 글

Vue - router  (0) 2022.06.10
Vue - method  (0) 2022.06.10
Vue - props / event emit  (0) 2022.06.08
Vue - Instance  (0) 2022.05.30
Vue - Vue 란?  (0) 2022.05.26
댓글