[Vue.js] 기초-뷰 컴포넌트

Taeho Min·2021년 9월 24일
0

Vue.js

목록 보기
1/7

1. 컴포넌트 등록

1.1 전역 컴포넌트 등록

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

1.2 지역 컴포넌트 등록

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

[인스턴스 유효 범위와 지역 컴포넌트, 전역 컴포넌트 간 관계 확인 예제]

두 번째 인스턴스에는 로컬 컴포넌트가 등록되지 않았으므로 오류가 표시 된다.

<html>
    <head>
        <title>인스턴스 유효 범위와 지역 컴포넌트, 전역 컴포넌트 간 관계 확인 예제</title>
    </head>
    <body>
        <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 src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
        <script>
            // 전역 컴포넌트
            Vue.component('my-global-component', {
                template: '<div>전역 컴포넌트 입니다.</div>'
            });
            
            // 지역 컴포넌트
            var cmp = {
                template: '<div>지역 컴포넌트 입니다.</div>'
            };
            
            // 첫 번째 인스턴스
            new Vue({
                el: '#app'
                components: {
                    'my-local-component': cmp
                }
            });
            
            // 두 번째 인스턴스
            new Vue({
                el: '#app2'
            });
        </script>
    </body>
</html>   

2. 뷰 컴포넌트 통신

상위-하위 컴포넌트 간에 데이터를 전달하는 기본 구조는 다음과 같다.

2.1 상위에서 하위 컴포넌트로 데이터 전달

Vue.component('child-component', {
   props: ['props 속성 이름'],
}

<child-component v-bind:props 속성 이름="상위 컴포넌트의 data 속성">

props는 상위 컴포넌트에서 하위 컴포넌트로 데이터를 전달할 때 사용하는 속성이다.
1) 하위 컴포넌트를 등록할 때 props 속성으로 하위 컴포넌트에서 사용할 속성을 지정한다.
2) child-component 태그에서 v-bind 속성의 왼쪽 값으로 1)에서 지정한 속성을 지정하고, 오른쪽 값으로 전달할 상위 컴포넌트의 data 속성을 지정한다.

[상위에서 하위 컴포넌트로 데이터 전달 예제]

<html>
    <head>
        <title>상위에서 하위 컴포넌트로 데이터 전달 예제</title>
    </head>
    <body>
        <div id="app">
            <!-- 팁: 오른쪽에서 왼쪽으로 속성을 읽으면 수월 함 -->
            <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', {
                props: ['propsdata'],
                template: '<p>{{ propsdata }}</p>'
            });
            
            // 인스턴스
            new Vue({
                el: '#app'
                data: {
                    message: 'Hello Vue! passed from Parent Component'
                }
            });
        </script>
    </body>
</html>   

2.2 하위에서 상위 컴포넌트로 이벤트 전달

Vue는 앵귤러의 양방향 데이터 바인딩과 리액트의 단방향 데이터 흐름의 장점을 결합한 프레임워크로, 상위 컴포넌트에서 하위 컴포넌트 한 방향으로만 데이터를 전달 하도록 구조화 되어 있기 때문에 하위에서 상위 컴포넌트로 데이터를 전달할 수 없다.

하위 컴포넌트에서 상위 컴포넌트로의 통신은 이벤트를 발생시켜(event emit) 상위 컴포넌트에 신호를 보내면 된다. 상위 컴포넌트는 하위 컴포넌트의 특정 이벤트를 수신하여 상위 컴포넌트의 메서드를 호출하는 것이다.

이벤트 발생과 수신은 $emit()과 v-on 속성을 사용하여 구현한다.

// 이벤트 발생
this.$emit('이벤트명');

$emit를 호출하면 괄호 안에 정의 된 이벤트가 발생한다. 그리고 일반적으로 $emit()을 호출하는 위치는 하위 컴포넌트의 특정 메서드 내부이다. 따라서 $emit()을 호출할 때 사용하는 this는 하위 컴포넌트를 가리킨다.

// 이벤트 수신
<child-component v-on:이벤트명="상위 컴포넌트의 메서드명">

[하위-상위 컴포넌트간 이벤트 발생 및 수신 예제]

<html>
    <head>
        <title>하위-상위 컴포넌트간 이벤트 발생 및 수신 예제</title>
    </head>
    <body>
        <div id="app">
            <child-component v-on:show-log="printText"></child-component>
        </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>',
                methods: {
                    showLog: function() {
                        this.$emit('show-log');
                    }
                }
            });
            
            // 인스턴스
            new Vue({
                el: '#app'
                data: {
                    message: 'Hello Vue! passed from Parent Component'
                },
                methods: {
                    printText: function() {
                        console.log('received an event');
                    }
                }
            });
        </script>
    </body>
</html>   

2.3 관계없는 컴포넌트 간 통신 - 이벤트 버스

이벤트 버스는 컴포넌트간 상위-하위 구조를 유지하지 않아도 개발자가 지정한 2개의 컴포넌트 간에 데이터를 주고받을 수 있는 방법이다.

이벤트 버스를 활용하면 props 속성을 이용하지 않아도 원하는 컴포넌트 간에 직접적으로 데이터를 전달할 수 있어서 편리하지만 컴포넌트가 많아지면 어디서 어디로 보냈는지 관리가 되지 않는 문제가 발생한다. 이 문제를 해결하려면 Vuex라는 상태 관리 도구가 필요하다.

// 이벤트 버스를 위한 추가 인스턴스 1개 생성
var eventBus = new Vue();

// 이벤트를 보내는 컴포넌트
methods: {
   메서드명: function() {
       eventBus.$emit('이벤트명', '데이터');
   }
}

// 이벤트를 받는 컴포넌트
methods: {
   created: function() {
       eventBus.$on('이벤트명', function(데이터) {
           ...
       });
   }
}

이벤트 버스를 구현하려면 로직을 담는 인스턴스와는 별개로 새로운 인스턴스를 1개 생성하고,
생성한 인스턴스를 이용하여 이벤트를 보내고 받는다.
보내는 컴포넌트에서는 .$emit()을, 받는 컴포넌트에서는 .$on을 구현한다.

[이벤트 버스 예제]

<html>
    <head>
        <title>이벤트 버스 예제</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();
            
            Vue.component('child-component', {
                template: '<div>하위 컴포넌트 영역입니다.<button v-on:click="showLog">show</button>',
                methods: {
                    showLog: function() {
                        eventBus.$emit('triggerEventBus', 100);
                    }
                }
            });
            
            // 인스턴스
            new Vue({
                el: '#app'
                created: function() {
                    eventBus.$on('triggerEventBus', function(value) {
                        console.log("이벤트를 전달받음. 전달받은 값 : ", value);
                    });
                },
            });
        </script>
    </body>
</html>   

# Books

  • Do it! Vue.js 입문 예제로 이해하고 실전 프로젝트로 완성한다! [장기효 저, 이지스퍼블리싱]
profile
개발자

0개의 댓글

관련 채용 정보