■■▶뷰_Vue.js◀( 2024. 6. 8. 17:30

 

 

 

1. Vue Component 통신

component로 화면을 구성합니다. 같은 웹 페이지안의 component라도 서로 데이터를 공유할 수 없습니다.

그 이유는 component 자체적으로 고유한 scope를 가지기 때문입니다. 따라서 각 컴포넌트의 유효 범위가 독립적이기 때문에 다른 컴포넌트의 값을 직접적으로 참조할 수 없습니다.

그러면 어떻게 해야 하나요?


2. 상, 하위 컴포넌트 관계일 경우

Vue가 가지고 있는 가장 기본적인 데이터 전달 방식은 상위(부모) - 하위(자식) 컴포넌트 간의 데이터 전달 방법입니다.

상위-하위 컴포넌트란 트리 구조에서 부모노드, 자식노드처럼 컴포넌트간의 관계가 부모, 자식으로 이루어진 컴포넌트를 의미합니다.

우리가 앞에서 살펴본 것처럼 인스턴스가 지역 혹은 전역 컴포넌트를 등록하면 등록된 컴포넌트는 자연스럽게 인스턴스의 하위 컴포넌트가 됩니다. 당연히 컴포넌트를 등록한 인스턴스는 상위 컴포넌트가 되는 것이구요.

다음의 그림은 Vue에서 상위-하위 컴포넌트간에 데이터를 전달하는 기본적인 구조를 나타냅니다.

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <child-component v-bind:propsdata="message"></child-component>
    </div>

    <script src='https://unpkg.com/vue'></script>
    <script>
        const app = Vue.createApp({
            name: 'App',
            data() {
                return {
                    message: '소리없는 아우성!!'
                }
            }
        })

        // 전역 컴포넌트 등록
        app.component('child-component', {
            data() {
                return {}
            },
            props: {
                propsdata: String            
            },
            template: '<p>전달된 데이터는 : {{ propsdata }}</p>'

        })

        const vm = app.mount('#app')
    </script>
</body>
</html>

 


3. 하위에서 상위 컴포넌트로 이벤트 전달하기

이벤트 발생과 수신에 대해서 알아보겠습니다. 앞에서 배운 props는 상위에서 하위 컴포넌트로 데이터를 전달하는 방식입니다.

그럼 반대로 하위 컴포넌트에서 상위 컴포넌트로의 통신은 어떻게 할까요? event를 emit시켜 상위 컴포넌트에 신호를 보내면 됩니다.

상위 컴포넌트에서는 하위 컴포넌트의 특정 이벤트가 발생하기를 기다리고 있다가 하위 컴포넌트에서 특정 이벤트가 발생하면 상위 컴포넌트에서 해당 이벤트를 수신하여 상위 컴포넌트의 메소드를 호출하는 방식을 사용합니다.

여기서 아까 언급한 내용에 대해 첨언을 하자면 Vue는 공식적으로 event 발생 시 하위에서 상위로 데이터를 전달하는 방법을 다루지 않습니다. 이는 편리하긴 하지만 기본적인 단방향 데이터 흐름에 어긋나기 때문입니다. 따라서 이 경우에는 Event Bus라고 불리는 다른 방식을 사용할 것입니다.

이벤트 발생과 수신 형식을 알아보죠. 이벤트 발생과 수신은 $emit()와 v-on: 속성을 사용하여 구현합니다.

 
 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <child-component v-on:show-log="printText"></child-component>
    </div>

    <script src='https://unpkg.com/vue'></script>
    <script>
        const app = Vue.createApp({
            data() {
               return {
                message: '소리없는 아우성!!'
               } 
            },
            methods: {
                printText: function(...args) {
                    console.log(args[0]) // 100
                    console.log(args[1]) // Hello
                    console.log(args[2].msg) // 이벤트 전달 데이터
                }
            }
        })

        app.component('child-component', {
            methods : {
                showLog: function() {
                    // 이벤트를 발생시킬 꺼예요!
                    // 아까는 버튼을 눌러서 이벤트를 발생시켰는데
                    // 이번에는 프로그램적으로 이벤트를 발생시킬 꺼예요!
                    this.$emit('show-log', 100, 'Hello', {
                        msg : '이벤트 전달 데이터'
                    })
                }
            },
            template: '<button v-on:click="showLog">클릭클릭!!</button>'
        })

        const vm = app.mount('#app')
    </script>
</body>
</html>

4. 같은 레벨의 컴포넌트 간 통신

지금까지는 상위에서 하위로 props를 전달하고 하위에서 상위로 이벤트를 전달하는 내용에 대해서 알아봤습니다. 이번에는 상위-하위 관계가 아니라 같은 레벨에 있는 컴포넌트끼리 어떻게 통신하는지를 알아보죠.

그림으로 표현하면 다음과 같습니다.


5. 연습문제

component간 통신과 event전달에 대한 간단한 문제를 한 풀어보도록 하겠습니다.

아래 그림과 같이 화면을 구성하고 버튼을 클릭했을 때 입력상자안의 내용을 event 전달을 통해 상위 component로 전달하고 다시 props로 내려받아 특정 div에 해당 내용을 출력하는 예제입니다.

 

++ 힌트 소스코드!!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>    
</head>
<body>
    <div id="app">
        <div>
            <global-component-a></global-component-a>
            <global-component-b></global-component-b>
        </div>
    </div>
    <script src='https://unpkg.com/vue'></script>
    <script>
        const app = Vue.createApp({
            data() {
                return {}
            }
        })

        app.component('global-component-a', {            
            template: `
                <div>
                    <local-component-c></local-component-c>
                    <local-component-d></local-component-d>
                </div>
            `,
            components: {
                'local-component-c': {
                    template: '<div>Local Component C</div>'
                },
                'local-component-d': {
                    template: `
                    <div>
                        <div>Local Component D</div>
                        <div>전달된 데이터 : {{ }}</div>
                    </div>
                    `
                },
            }
        })

        app.component('global-component-b', {
            template: `
                <local-component-f></local-component-f>
            `,
            components: {
                'local-component-f': {
                    template: `
                    <div>
                        <input type="text" id="inputText">
                        <button>클릭클릭</button>
                    </div>
                    `
                }
            }
        })

        app.mount('#app')
    </script>
</body>
</html>

 

힌트... 소스코드!!

'■■▶뷰_Vue.js◀(' 카테고리의 다른 글

07-Vue.js / Single File Component  (0) 2024.06.09
06-Vue.js / Directive  (0) 2024.06.09
04-Vue.js / Component  (0) 2024.06.08
03-Vue.js / Instance  (0) 2024.06.08
02-Vue.js / 환경설정  (0) 2024.06.08
posted by [서ㄹ하 雪河 Selha YoonSem]
: