Introduction

Icon

Vue로 화면을 개발하기 위해 필수적으로 생성해야 하는 기본 단위는 인스턴스(Instance)입니다.

2장에서 'Hello Vue.js!' 가 출력될 수 있었던 것은 인스턴스가 생성되었기 때문입니다. 그리고 1장에서 Vue의 특징 중 하나를 컴포넌트(Component)기반 이라고 설명하였습니다.

컴포넌트란 화면을 블록처럼 조합하여 화면을 구성할 수 있도록 하는 단위입니다.

 

이 글에서는 인스턴스와 컴포넌트에 대해서 설명하겠습니다.

Prerequisite

Icon

생성자 - https://ko.wikipedia.org/wiki/%EC%83%9D%EC%84%B1%EC%9E%90

인스턴스 - https://ko.wikipedia.org/wiki/%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4

컴포넌트 - https://en.wikipedia.org/wiki/Component

라이프 사이클 - https://en.wikipedia.org/wiki/Program_lifecycle_phase

 

 

1. 인스턴스 생성

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<html>

  <head>

    <title>Vue Sample</title>

  </head>

  <body>

    <div id="app">

      {{ message }}

    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>

    <script>

      new Vue({

        el: '#app',

        data: {

          message: 'Hello Vue.js!'

        }

      });

    </script>

  </body>

</html>

앞장에서 다루었던 'Hello Vue.js!' 예제 입니다.

인스턴스를 생성하기 위해선 new Vue 라는 생성자를 호출해야 합니다. 생성자란 객체를 새로 생성할 때 자주 사용하는 옵션과 기능들을 미리 특정 객체에 저장해 놓고, 새로운 객체를 생성할 때 기존에 포함된 기능과 더불어 기존 기능을 쉽게 확장하여 사용하는 기법입니다

위 예제에는 생성자의 속성에 el, data와 같이 2개만 사용되었지만, template, methods, created 등 여러 가지 속성이 있습니다. 나머지 속성들은 뒷장에서 각각 설명하겠습니다.

 

 

2. 인스턴스의 유효 범위

 

Vue 인스턴스는 생성 후 HTML의 범위 내에서만 옵션 속성들이 적용됩니다. 이를 인스턴스의 유효 범위라 합니다. 컴포넌트 설명 부분에서 지역 컴포넌트와 전역 컴포넌트의 차이점을 이해하기 위해서도 꼭 알아야 하는 개념이며, 인스턴스의 유효 범위는 el 속성에 의해 정해집니다.

인스턴스가 생성된 후 화면에 적용되는 순서는 아래와 같습니다.

      1. Vue 라이브러리 로딩
      2. 인스턴스 객체 생성
      3. 특정 화면 element에 인스턴스를 연결
      4. 인스턴스의 내용이 element에 적용
      5. 적용된 화면이 사용자에게 노출

만약 'Hello Vue.js!' 예제를 아래처럼 수정한다면 어떻게 될까요

1

2

3

4

<div id="app">

 

</div>

{{ message }}

 

인스턴스 유효 범위를 벗어났기 때문에 message는 출력되지 않습니다.

 

 

 

3. 인스턴스 라이프 사이클

 

앞에 있는 인스턴스 생성 설명 부분에서 인스턴스의 속성 중 created라는 속성이 있습니다. 이처럼 Vue 인스턴스는 인스턴스 생성 중 인스턴스의 상태에 따라 호출할 수 있는 속성들인 라이프 사이클 속성들이 있습니다.

라이프 사이클과 해당 속성의 종류를 알아보겠습니다.

 

단계

설명

beforeCreate 

인스턴스가 생성되고 최초로 실행되는 단계. 이 단계에서는 data 속성과 methods 속성이 아직 인스턴스에 정의되어 잇지 않고, 화면 요소에도 접근할 수 없습니다.

created 

data, methods 속성의 정의된 단계. this.data 와 같이 사용할 수 있고 methods를 사용하여 로직을 실행할 수 있습니다. 하지만 아직 화면요소가 적용되기 전이기 때문에 template 속성에 정의된 요소에는 접근할 수 없습니다. 

그리고 data, methods 속성에 접근 할 수 있는 첫 단계이기 때문에 서버에 데이터를 요청하여 받아오는 로직을 수행하기 좋습니다. 서버에 데이터를 요청하는 방법은 이후 장에서 설명되겠습니다.

beforeMount 

template 속성에 지정한 마크업 속성을 render() 함수로 변환한 후 el 속성에 지정한 화면 요소에 인스턴스를 연결하기 전에 호출되는 단계. 

mounted 

 el 속성에서 지정한 화면 요소에 인스턴스가 연결되고 호출되는 단계. template 속성에 정의된 요소에 접근할 수 있어 화면 요소를 제어하는 로직을 수행하기 좋은 단계입니다.

beforeUpdate 

Vue의 특징 중 반응성(Reactivity)이 있습니다. 반응성이란 코드로 인한 데이터의 변화에 따라 화면이 즉각 반응하여 갱신되는 것을 의미합니다. 관찰되고 있는 데이터가 변화되어 화면으로 그려지기 직전에 호출되는 단계입니다. 

변경 예정된 데이터의 값에 대한 로직을 수행하기 좋은 단계입니다. 주의할 점은 이 단계에서 값을 변경하는 로직을 넣더라도 화면이 반응하지 않습니다.

update 

데이터가 변경된 후 화면에 반영된 후 실행되는 단계. 데이터 변경 후 화면 요소에 대한 제어 로직을 추가하기 좋습니다. 

beforeDestroy 

Vue 인스턴스가 소멸하기 직전에 단계. 아직 인스턴스에 접근할 수 있기 때문에 Vue 인스턴스의 데이터를 삭제하기 좋은 단계입니다.

destroyed 

Vue 인스턴스가 소멸하고 나서 호출되는 단계. 인스턴스에 정의한 모든 속성이 제거되고 하위로 선언한 인스턴스까지 모두 소멸합니다.

 

 

'Hello Vue.js!' 예제에서 라이프 사이클 속성 몇 가지를 추가해 보았습니다.

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

<html>

  <head>

    <title>Vue Instance Lifecycle</title>

  </head>

  <body>

    <div id="app">

      {{ message }}

    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>

    <script>

      new Vue({

        el: '#app',

        data: {

          message: 'Hello Vue.js!'

        },

        beforeCreate: function() {

          console.log("beforeCreate");

        },

        created: function() {

          console.log("created");

        },

        mounted: function() {

          console.log("mounted");

        },

        updated: function() {

          console.log("updated");

        }

      });

    </script>

  </body>

</html>

 

각 로그를 확인해보면 아래와 같습니다.

 

 

beforeCreate, created, mounted가 출력되었지만, updated 속성의 function은 호출되지 않았습니다. 인스턴스의 data 값이 변경된 적이 없기 때문에 실행되지 않았습니다. data 속성값을 변경해보겠습니다.

 

1

2

3

4

mounted: function() {

  console.log("mounted");

  this.message = 'Hello Vue!';

}

 

화면요소가 연결된 후 호출되는 단계인 mounted 에서 message 값을 수정해 보았습니다.

 

 

mounted 단계에서 message 값을 수정되었기 때문에 데이터 수정에 의한 반응으로 화면의 값이 바뀌고 updated 가 실행됨을 확인할 수 있습니다.

 

위와 같이 Vue 인스턴스의 라이프 사이클 단계에 따라 적절한 처리를 이용하면 화면 개발 시 유용하게 처리할 수 있습니다.

 

 

4. 컴포넌트 등록

 

컴포넌트 등록의 방법은 두 가지가 있습니다. 전역 컴포넌트, 지역 컴포넌트 두 가지로 용도에 따라 사용할 수 있습니다.

지역(Local) 컴포넌트는 정해진 특정 구역에서만 사용할 수 있는 컴포넌트이고, 전역(Global) 컴포넌트는 모든 인스턴스에서 공통으로 사용할 수 있는 컴포넌트입니다.

 

전역 컴포넌트 등록

1

2

3

Vue.component('컴포넌트 명', {

  //컴포넌트 속성

});

 

Vue 라이브러리를 로딩하고 나면 Vue라는 전역 변수가 생성됩니다. 해당 변수에 전역 컴포넌트를 등록 할 수 있습니다.

모든 Vue 인스턴스에서는 해당 컴포넌트에 접근하여 사용할 수 있습니다.

예제를 살펴보겠습니다.

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

<html>

  <head>

    <title>Vue Component Registration</title>

  </head>

  <body>

    <div id="app">

      <button>컴포넌트 등록</button>

      <my-component></my-component>

    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>

    <script>

      Vue.component('my-component', {

        template: '<div>전역 컴포넌트가 등록되었습니다!</div>'

      });

      new Vue({

        el: '#app'

      });

    </script>

  </body>

</html>

 

 

등록한 my-component가 등록되었고 template이라는 속성을 가지고 있습니다.

(template에 대한 자세한 설명은 6장에서 설명되겠습니다)

id app인 요소에 my-component를 사용하도록 선언하였고 전역에 등록되어있는 my-component template이 사용되었습니다.

크롬 브라우저에서 해당 화면에서 마우스 우클릭 후 소스 보기를 하면 아래와 같습니다.

 

 

하지만 브라우저에서 요소검사를 하면 아래와 같습니다.

 

 

소스 상에서는 <my-component></my-component> 으로 확인되지만, 동적으로 변한 최종화면에서는 <div>전역 컴포넌트가 등록되었습니다!</div> 로 확인됩니다.

 

지역 컴포넌트 등록

1

2

3

4

5

new Vue({

  components: {

    '컴포넌트 명': 컴포넌트 내용

  }

});

 

전역 컴포넌트와 마찬가지로 컴포넌트 명은 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

<html>

  <head>

    <title>Vue Component Registration</title>

  </head>

  <body>

    <div id="app">

      <button>컴포넌트 등록</button>

      <my-local-component></my-local-component>

    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>

    <script>

      var cmp = {

        // 컴포넌트 내용

        template: '<div>지역 컴포넌트가 등록되었습니다!</div>'

      };

      new Vue({

        el: '#app',

        components: {

          'my-local-component': cmp

        }

      });

    </script>

  </body>

</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

35

36

37

38

39

40

<html>

  <head>

    <title>Vue Local and Global Components</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개를 생성했습니다.

app, app2 두 인스턴스 모두 my-global-component, my-local-component를 인스턴스 유효 범위에서 사용하려 하고 있습니다.

하지만 app에서는 components에서 cmp를 등록하였고 app2에서는 등록하지 않았습니다. 모두 예상하는 대로 결과는 아래와 같습니다.

 

 

지역 컴포넌트는 인스턴스 속성의 components에 등록하지 않으면 사용할 수 없지만, 전역 컴포넌트는 모든 인스턴스에서 사용할 수 있습니다.

 

 

Conclusions

 

Vue의 인스턴스와 컴포넌트에 대해서 알아보았습니다.

인스턴스는 라이프 사이클을 유용하게 써야 하며, 컴포넌트는 전역, 지역 컴포넌트를 잘 구분하여 작성한다면 공통된 기능의 분리와 각각 업무나 기능별 컴포넌트를 분리하여 사용할 수 있겠습니다.

다음 장에서는 컴포넌트 간의 통신 관계에 대해서 알아보겠습니다.

 

 

References

Icon

https://kr.vuejs.org/v2/guide/

 

 

 

 

출처: <http://wiki.sys4u.co.kr/pages/viewpage.action?pageId=8553372>

 

Posted by 철냄비짱
,