본문 바로가기

기타/vue js

Vue.js 여러개 인스턴스 , 컴퍼넌트 개념과 컴포넌트 간 통신

728x90

오늘 학습할 내용은 Vue .js인스턴스, Vue 컴포넌트 개념과 컴포넌트 간 통신입니다.

1. 여러 개의 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>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="app">
        {{name}}
    </div>
    <div>
        {{name}}
    </div>
    <script>
        new Vue({
            el: "#app",
            data: {
                name: "발모스토리"
            }
        }
        )



    </script>
</body>

</html>

이렇게 하면 name이 나오지 않는다.

id 가 app이 아닌 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>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="app">
        {{name}}
    </div>
    <div>
        {{name}}
    </div>
    <div id="app-1">
        {{name}}
    </div>
    <script>
        new Vue({
            el: "#app",
            data: {
                name: "발모스토리"
            }
        }
        )
        new Vue({
            el: "#app-1",
            data: {
                name: "발모스토리1"
            }
        }
        )


    </script>
</body>

</html>

변수에 뷰인스턴스를 넣어줌으로써 함수에서 다른 뷰 인스턴스의 데이터를 바꿔줄 수 있다.

그렇다면 여기서 app에서 app-1 인스턴스 데이터로 접근하는 방법이 있을까??

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="app">
        {{name}}
        <button @click="changetext">변환</button>
    </div>
    <div id="app-1">
        {{name}}
        <button @click="changetext">변환</button>
    </div>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
                name: "발모스토리"
            },
            methods:{
                changetext(){
                    app_1.name = "발모스토리 update";
                }
            }
        }
        )
        const app_1=new Vue({
            el: "#app-1",
            data: {
                name: "발모스토리1"
            },
            methods:{
                changetext(){
                    app.name = "발모스토리1 update";
                }
            }
        }
        )


    </script>
</body>

</html>

뷰인 스턴스를 변수 안에 넣어주면 각 인스턴스 안의 메서드에서 접근할 수 있다.

여러 개의 뷰인스턴스를 다룰 때는 변수 안에 넣어주는 것이 중요하다.

 

2.Vuejs 컴포넌트 다루기.

중복되는 함수, 데이터 제거하기 위해 사용하는 것이 컴포넌트입니다.

전역 등록 방식과 지역 등록 방식이 있는데요.

전역 등록 방식 먼저 알아보도록 하겠습니다.

 

(1) 전역 등록 방식

뷰 객체의 component를 생성해주고 기존의 코드에서 공통된 코드들을 넣어줍니다.

html 코드는 template에 넣어줍니다.

data 데이터의 경우 함수로 바꿔주어야 한다.

이유는 재사용하는 컴포넌트의 경우 object가 주소로 넘어가 컴포넌트가 사용될 때마다 데이터가 변경되면 그 주소에 있는 데이터가 전부 업데이터 되기 때문에 다른 곳에서도 같이 업데이트되기 때문에 함수로 변경해야 한다.

(이해가 안 가신다면 컴포넌트에서는 함수로 리턴해서 값을 준다고 기억해주세요.)

 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="app">

        <balmobutton></balmobutton>
    </div>
    <hr>
    <hr>
    <div id="app-1">

        <balmobutton></balmobutton>
    </div>
    <script>
        Vue.component('balmobutton', {
            template: `
            <div>
                {{name}}<br>
                <button @click="changetext">변환</button>
            </div>
            `,
            data() {
                return {
                    name: "발모스토리"
                }
            },
            methods: {
                changetext() {
                    this.name = "발모스토리 update";
                }
            }
        })
        const app = new Vue({
            el: "#app"
        }
        )
        const app_1 = new Vue({
            el: "#app-1"
        }
        )


    </script>
</body>

</html>

이렇게 나오고 변환을 누르면 누른 부분의 값만 업데이트됩니다.

 

(2) 지역 등록 방식

전역 등록의 경우 컴포넌트가 최종 빌드에 들어가기 때문에 사용이 제한된 컴포넌트까지 계속 유지되어 자바스크립트의 양이 불필요하게 많아질 수 있습니다.

때문에 경우에 따라 지역 등록을 사용할 필요가 있습니다.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="app">

        <balmobutton></balmobutton>
    </div>
    <hr>
    <hr>
    <div id="app-1">

        <balmobutton></balmobutton>
    </div>
    <script>
        const balmobutton = {
            template: `
            <div>
                {{name}}<br>
                <button @click="changetext">변환</button>
            </div>
            `,
            data() {
                return {
                    name: "발모스토리"
                }
            },
            methods: {
                changetext() {
                    this.name = "발모스토리 update";
                }
            }
        }
        const app = new Vue({
            el: "#app",
            components: {
                'balmobutton': balmobutton
            }
        }
        )
        const app_1 = new Vue({
            el: "#app-1"
        }
        )


    </script>
</body>

</html>

보시면 app에서는 제대로 작동하지만 app-1에서는 컴포넌트를 넣지 않았기 때문에 에러가 발생하는 것을 볼 수 있습니다.

 

(3) 컴포넌트 간 통신

helloworld라는 새로운 컴포넌트를 만들고 balmobutton의 컴포넌트 객체 안에 helloworld를 넣어주면 template안에서 사용할 수 있습니다.

helloworld 컴포넌트를 전역으로 만들었다면 컴포넌트 객체 안에 넣어주지 않아도 작동합니다.

아래 예시는 지역적으로 생성해 통신하는 것을 보여드린 것입니다.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="app">

        <balmobutton></balmobutton>
    </div>
    <hr>
    <hr>
    <div id="app-1">

        <balmobutton></balmobutton>
    </div>
    <script>
        const helloworld = {
            template:`
            <div>
                hello_world
            </div>
            `
        }
        const balmobutton = {
            components:{
                "helloworld":helloworld
            }
            ,
            template: `
            <div>
                {{name}}<br>
                <helloworld></helloworld>
                <button @click="changetext">변환</button>
            </div>
            `,
            data() {
                return {
                    name: "발모스토리"
                }
            },
            methods: {
                changetext() {
                    this.name = "발모스토리 update";
                }
            }
        }
        const app = new Vue({
            el: "#app",
            components: {
                'balmobutton': balmobutton
            }
        }
        )
        const app_1 = new Vue({
            el: "#app-1"
        }
        )


    </script>
</body>

</html>

 

728x90