본문 바로가기
관리자

Programming-[Frontend]/Vue.js

Vue.js / 기초 / 5. 인스턴스, 컴포넌트

728x90
반응형

1. 인스턴스

여러 개의 인스턴스 생성하기

new Vue 명령어를 통해서 Vue를 생성하고, el 객체에서 적용되는 id값만 바꿔서 적용해주면 된다. id=app 과 id=app2인 요소를 2개 만들고, 같은 인스턴스를 만들고 같은 메서드를 적용하되, el객체의 값을 바꿔주었다.(instance.html 파일)

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<body>
<div id="app">
    {{name}} <br>
    <button @click="changeName()">change</button>
</div>
<div id="app2">
    {{name}} <br>
    <button @click="changeName()">change</button>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            name'charlie'
        },
        methods: {
            changeName() {
                this.name = this.name + ' changed';
            }
        }
    }),
        new Vue({
            el: '#app2',
            data: {
                name'charlie2'
            },
            methods: {
                changeName() {
                    this.name = this.name + ' changed';
                }
            }
        })
</script>
</body>
cs

 

 

 

다른 인스턴스의 data에 접근하기

각 인스턴스를 변수로 지정한다(const app1, const app2). 그리고 this 대신 접근을 원하는 인스턴스를 참조하는 변수 이름을 사용하면 된다. 2개의 각 인스턴스를 app1, app2로 지정하고 app1의 methods에서 app2.name을 변경하도록 하였다. app2에서도 같은 방식으로 적용하면 서로의 data.name 값을 바꿔줄 수 있게 된다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<script>
    const app1 = new Vue({
        el: '#app',
        data: {
            name'charlie'
        },
        methods: {
            changeName() {
                app2.name = app2.name + ' changed';
            }
        }
    });
        const app2 = new Vue({
            el: '#app2',
            data: {
                name'charlie2'
            },
            methods: {
                changeName() {
                   app1.name = app1.name + ' changed';
                }
            }
        });
</script>
cs

 


 

2. 컴포넌트

 

컴포넌트란?

컴포넌트도 하나의 인스턴스이다. 위의 인스턴스 예시에서처럼 같은 코드를 갖는 인스턴스를 여러 개 중복해서 작성할 필요없고, 컴포넌트로 작성해서 불러오면 중복이 제거될 뿐만 아니라 가독성에도 좋게 된다. 다시 말해 인스턴스를 모듈화한 것을 컴포넌트라 한다. 다만, 컴포넌트는 렌더링을 해주는 Vue 인스턴스가 필요하여 인스턴스 내부에 작성해야 한다. 만약 'compo'라는 이름을 갖는 컴포넌트를 작성하면, <compo>라는 태그를 갖는 컴포넌트를 인스턴스 내부에서 사용할 수 있게 된다고 이해하면 된다. 컴포넌트는 아래와 같은 문법으로 작성한다.

 

Vue.component(tagName, options)

 

컴포넌트 사용방법 : 전역 등록

파라미터 중, tagName은 컴포넌트의 이름을 문자열로 입력해주는 부분이고, options 부분에 기존 인스턴스의 data, methods등이 들어가게 된다.하지만 template 적용, 객체 함수화 등 인스턴스와 다른 점이 있는데, 아래 코드를 보면서 이해해보자.(component.html 파일. instance.html 파일을 갖다쓰자)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<body>
<div id="app1">
    {{name}} <br>
    <compo></compo>
</div>
<hr>
<script>
        const compo = Vue.component('compo', {
        template:
        `
        <div>
        {{name}} <br>
        <button @click="changeName"> change </button>
        </div>
        `,
        data(){
            return {
                name : "charlie_Combo"
            }
        },
        methods: {
            changeName() {
                this.name = this.name + " changed";
            }
        }
    });
    const app1 = new Vue({
        el: '#app1',
        data: {
            name"charlie"
        }
    })
</script>
</body>
cs

 

 

 

template

options 파라미터를 적는 곳에 template 객체를 추가해야한다. 이 객체 안에 화면에 표시하고자하는 html 태그 등을 넣으면 된다. 다만 여러 줄로 구성된 경우 일반 따옴표가 아니라 백틱(`)으로 감싸줘야한다. 그리고 template 객체는 react와 같이 모든 태그들을 감싸는 최외곽 태그가 1개 있어야 한다. Vue.js 3에서는 이러한 제한 사항이 없다.

 

data

컴포넌트는 위와 같이 data 부분을 함수로 지정해주어야 한다. 함수로 지정해주지 않으면 data 내부의 객체 값들이 모든 곳에서 업데이트 되기 때문이라고 하는데, 정확한 이해는 추후에 자세히 공부해봐야 될 것 같다. 컴포넌트 정의가 완료되면 tagName을 기반으로 일반 html 태그처럼 사용하면 된다.

 

컴포넌트 위치

컴포넌트는 인스턴스와 같이 단독으로 쓰일 수 있지만, 렌더링을 해주는 기본적인 인스턴스가 있어야 활용이 가능하다. 또한 <script> 태그 내에서 컴포넌트의 선언부가 인스턴스의 선언부보다 앞쪽에 위치해야 한다.

 

출력 결과

컴포넌트 중첩

컴포넌트 안에 다른 컴포넌트를 넣어서 사용할 수도 있다. 아래 예시와 같이 greeting 이라는 컴포넌트를 만들고, compo 컴포넌트 내부에 삽입하여 렌더링이 되도록 해보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
    const greeting = Vue.component('greeting', {
        template:
            `
            <div> hello </div>
            `
    })
        const compo = Vue.component('compo', {
        template:
        `
        <div>
        {{name}} <br>
        <greeting></greeting>
        <button @click="changeName"> change </button>
        </div>
        `,
cs

 

 

지역등록

전역 등록된 컴포넌트는 프로젝트 내의 어디서든 사용할 수 있지만, 더 이상 사용하지 않더라도 최종 빌드 파일에는 들어가 있게 되어 자바스크립트 파일의 용량이 불필요하게 커지게 된다. 따라서 가능하다면 지역등록으로 처리해주는 것이 좋다. 컴포넌트를 지역 등록 하기 위해서는 인스턴스 내부에 components 객체를 만들고, 그 안에 변수로 지정한 컴포넌트를 불러와야 한다.

 

<body> 부분 전체 코드. 필요 시에만 보자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<body>
<div id="app1">
    {{name}} <br>
    <compo></compo>
</div>
<hr>
<script>
    const greeting = Vue.component('greeting', {
        template:
            `
            <div> hello </div>
            `
    })
    const compo = Vue.component('compo', {
        components: {
            'greeting': greeting
        },
        template:
            `
        <div>
        {{name}} <br>
        <greeting></greeting>
        <button @click="changeName"> change </button>
        </div>
        `,
        data() {
            return {
                name"charlie_Combo"
            }
        },
        methods: {
            changeName() {
                this.name = this.name + " changed";
            }
        }
    });
    const app1 = new Vue({
        el: '#app1',
        data: {
            name"charlie"
        },
        components: {
            'compo': compo
        }
    })
</script>
</body>
cs

 

 

 

body 바로 아래 요소 부분

1
2
3
4
5
6
<body>
<div id="app1">
    {{name}} <br>
    <compo></compo>
</div>
<hr>
cs

인스턴스 정의 부분

1
2
3
4
5
6
7
8
9
const app1 = new Vue({
        el: '#app1',
        data: {
            name: "charlie"
        },
        components: {
            'compo': compo
        }
    })
cs

 

 

기존 컴포넌트 대신 compo 라는 변수를 정의하여 컴포넌트의 내용을 넣어주고, app1 인스턴스에 components 객체를 만들어서 변수 이름으로 컴포넌트를 불러오는 방식이다.

 

compo 컴포넌트 안에 greeting 컴포넌트를 지역등록할 수도 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const compo = Vue.component('compo', {
        components: {
            'greeting': greeting
        },
        template:
            `
        <div>
        {{name}} <br>
        <greeting></greeting>
        <button @click="changeName"> change </button>
        </div>
        `,
        data() {
            return {
                name: "charlie_Combo"
            }
        },
        methods: {
            changeName() {
                this.name = this.name + " changed";
            }
        }
    });
cs

 

전역변수로 선언했을 때와 동일하게 출력되는 것을 확인할 수 있다.


참조

 

1) 유튜브 코지코더 - '뷰js 2 기초익히기 시리즈'

www.youtube.com/channel/UCI4tTBupvhMX1aWDSm-HAXwkr.vuejs.org/v2/guide/comparison.html

 

728x90
반응형