Front-End/Vue.js 2019. 8. 10. 21:40

 

뷰 인스턴스의 정의와 속성

뷰 인스턴스는 뷰로 화면을 개발하기 위해 필수적으로 생성해야 하는 기본 단위이다. 즉 뷰로 화면을 개발하기 위해 빠트릴 수 없는 필수 조건이다.

 

뷰 인스턴스 생성

뷰 인스턴스를 사용하기 위해 아래와 같은 형식으로 뷰 인스턴스를 생성한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<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>
 
cs

위의 코드를 간단히 설명하자면 HTML화면에 'Hello Vue.js !' 라는 텍스트를 출력하기 위한 코드이다. 일단 new Vue()로 뷰 인스턴스를 생성하였다. 물론 이전에 Vue 인스턴스를 사용할 수 있게 vue.js 라이브러리를 내려받고 있는 코드가 존재한다. 그리고 인스턴스 안에 el 속성으로 해당 뷰 인스턴스의 범위를 설정해주었고, data 속성에 message 값을 정의하여 화면의 {{message}}에 'Hello Vue.js !'가 출력되도록 하였다. 잘 보면 el의 범위가 특정 div의 아이디 값과 매칭되는 것이 보인다.(css 선택자) 즉, 해당 뷰 인스턴스는 app이라는 아이디를 가진 특정 HTML 태그라는 범위를 갖고 사용되는 인스턴스인 것이다.

 

뷰 인스턴스 옵션 속성

뷰 인스턴스 옵션 속성은 인스턴스를 생성할 때 재정의할 data, el, template 등의 속성을 의미한다. 이 말은 무엇이냐, 이미 Vue 인스턴스에는 el,data,template 등의 속성이 선언되어 있지만 우리가 뷰 인스턴스를 생성할 때 해당 옵션들을 재정의 할 수 있다는 것이다. 위 코드에서는 data라는 미리 선언된 옵션에 message 라는 data(key/value)를 재정의 하였고 해당 값을 HTML 태그 내에서 사용하는 것을 볼 수 있다. 또한 해당 뷰 인스턴스의 범위(el)옵션을 '#app'으로 재정의하고 있다. 여기서 '#app'은 id가 app인 특정 돔 요소를 뜻한다.

 

속성 설명
template 화면에 표시할 HTML, CSS 등의 마크업 요소를 정의하는 속성. 뷰의 데이터 및 기타 속성들도 함께 화면에 그릴 수 있다.
methods 화면 로직 제어와 관계된 메소드를 정의하는 속성. 마우스 클릭 이벤트 처리와 같이 화면의 전반적인 이벤트와 화면 동작과 관련된 로직을 추가 할 수 있다.
created 뷰 인스턴스가 생성되자마자 실행할 로직을 정의할 수 있는 속성. 뷰 인스턴스의 라이프 사이클과 관련된 속성이다. created 이외에 많은 라이프 사이클 훅을 정의할 수 있는 옵션이 존재한다.

 

뷰 인스턴스의 유효 범위

위에서 뷰 인스턴스의 유효범위라는 단어가 포함된 설명이 존재하였다. 그렇다면 자세히 뷰 인스턴스의 유효범위에 대하여 다루어보자. 뷰 인스턴스를 생성하면 HTML의 특정 범위 안에서만 옵션 속성들이 적용되어 나타난다. 이를 인스턴스의 유효 범위라고 한다. 다음 포스팅에서 다루어볼 "지역,전역 컴포넌트 이해"에도 중요한 내용이니 꼭 기억해야한다. 위에서 말했듯이 뷰 인스턴스의 유효범위는 el 속성과 밀접한 관계가 있다.

 

뷰 인스턴스의 유효 범위를 이해하려면 실제로 인스턴스의 라이플 사이클을 이해할 필요가 있다.

 

 

우리가 위에서 작성한 코드는 위의 라이프 사이클 흐름중 인스턴스를 화면에 부착하는 것까지의 행위를 정의한다. 먼저 자바스크립트 코드 상에서 인스턴스 옵션 속성 el과 data를 인스턴스에 정의하고 인스턴스를 생성하였다. 그리고 브라우저에서 코드를 실행시키면 el 속성에 지정된 HTML의 특정 돔요소에 인스턴스가 부착된다.(부착된다의 의미를 그냥 적용된다라고 이해해도 좋다.) el 속성에 해당하는 특정 돔 요소에 뷰 인스턴스가 부착되고 나면 인스턴스에 정의한 data 속성이 el 속성에 지정한 특정 돔 요소에 값이 적용되고 화면의 {{message}}가 'Hello Vue.js !'라는 텍스트로 치환된다.

 

이해하기 힘들면 '아 그렇구나 !'하고 넘어가도 좋다. 나중 포스팅에서 다시 다루어보면서 해당 의미를 다시 한번 정확히 파악해 볼것이고, 이번 포스팅에서는 뷰가 무엇이고 어떻게 간단히 사용되는지 설명하는 포스팅이다.

 

그렇다면 현재 <div id="app"></div> 안에 있는 {{message}}를 해당 태그 밖으로 빼보자. 어떻게 되는가? {{message}}라는 문자열이 그대로 화면에 출력되는 것이 보일 것이다. 이것이 바로 뷰 인스턴스의 유효범위이다. app이라는 아이디를 가진 특정 돔 요소에서 벗어나 버리면 뷰 인스턴스에 정의한 data를 사용할 수가 없는 것이다. 꼭 기억하자.

 

뷰 인스턴스 라이프 사이클

앞에서 살펴본 뷰 인스턴스 옵션 중 created라는 속성을 기억할 것이다. 해당 옵션은 인스턴스가 생성되었을 때 호출할 동작을 정의하는 속성이라고 설명하였다. 이처럼 인스턴스의 상태에 따라 호출할 수 있는 속성들을 라이프 사이클 속성이라고 한다. 그리고 각 라이프 사이클 속성에서 실행되는 커스텀 로직을 라이프 사이클 훅이라고 한다. 위의 그림에서 beforeUpdate, updated 사이클은 데이터의 변경이 없다면 지나지 않는 라이프 사이클임을 주의하자.

 

라이프 사이클 속성에는 총 8개가 존재한다. 위의 그림을 같이 참조하여 살펴보자.

 

속성 설명
beforeCreate 인스턴스가 생성되고 나서 가장 처음으로 실행되는 라이프 사이클 단계이다. 이 단계에서는 data 속성과 methods 속성이 아직 인스턴스에 정의되어 있지 않고, 돔과 같은 화면 요소에도 접근할 수 없다.
created

beforeCreate 라이프 사이클 단계 다음에 실행되는 단계이다. data 속성과 methods 속성이 정의되었기 때문에 this.data 또는 this.fetchData()와 같은 로직들을 이용하여 data 속성과 methods 속성에 정의된 값에 접근하여 로직을 실행할 수 있다. 다만, 아직 인스턴스가 화면 요소에 부착되기 이전이기 때문에 template 속성에 정의된 돔 요소로 접근할 수 없다.

data 속성과 methods 속성에 접근할 수 있는 가장 첫 라이프 사이클 단계이자 컴포넌트가 생성되고 나서 실행되는 단계이기 때문에 서버에 데이터를 요청하여 받아오는 로직을 수행하기 좋다.

beforeMount

created 단계 이후 template 속성에 지정한 마크업 속성을 render() 함수로 변환한 후 el 속성에 지정한 특정 화면 요소에 인스턴스를 부착하기 전에 호출되는 단계이다. render()가 호출되기 이전에 로직을 추가하기 좋다.

 

render() - 자바스크립트로 화면의 돔을 그리는 함수

mounted

el 속성에서 지정한 화면 요소에 인스턴스가 부착되고 나면 호출되는 단계로, template 속성에 정의한 화면 요소에 접근할 수 있어 화면 요소를 제어하는 로직을 수행하기 좋은 단계이다. 다만, 돔에 인스턴스가 부착되자마자 바로 호출되기 때문에 하위 컴포넌트나 외부 라이브러리에 의해 추가된 화면 요소들이 최종 HTML 코드로 변환되는 시점과 다를 수 있다.

변환되는 시점이 다를 경우 $nextTick() API를 이용하여 HTML 코드로 최종 파싱될 때까지 기다린 후 돔 제어 로직을 추가한다.

beforeUpdate

el 속성에서 지정한 화면 요소에 인스턴스가 부착되고 나면 인스턴스에 정의한 속성들이 화면에 치환된다. 치환된 값은 뷰의 반응성을 제공하기 위해 $watch 속성으로 감시한다.

또한 beforeUpdate는 관찰하고 있는 데이터가 변경되면 가상 돔으로 화면을 다시 그리기 전에 호출되는 단계이며, 변경 예정인 새 데이터에 접근할 수 있어 변경 예정 데이터의 값과 관련된 로직을 미리 넣을 수 있다. 

 

뷰의 반응성 : 뷰의 특징 중 하나로, 코드의 변화에 따라 화면이 반사적으로 반응하여 빠르게 화면을 갱신하는 것을 의미.

updated 데이터가 변경되고 나서 가상 돔으로 다시 화면을 그리고나면 실행되는 단계이다. 데이터 변경으로 인한 화면 요소 변경까지 완료된 시점이므로, 데이터 변경 후 화면 요소 제어와 관련된 로직을 추가하기 좋은 단계이다. 이 단계에서 데이터 값을 변경하면 무한 루프에 빠질 수 있기 때문에 값을 변경하려면 computed, watch 와 같은 속성을 사용해야 한다. 따라서 데이터 값을 갱신하는 로직은 가급적이면 beforeUpdate에 추가하고, updated에서는 변경 데이터의 화면 요소와 관련된 로직을 추가하는 것이 좋다.
beforeDestroy 뷰 인스턴스가 파괴되기 직전에 호출되는 단계이다. 이 단계에서는 아직 인스턴스에 접근할 수 있다. 따라서 뷰 인스턴스의 데이터를 삭제하기 좋은 단계이다.
destroyed 뷰 인스턴스가 파괴되고 나서 호출되는 단계이다. 뷰 인스턴스에 정의한 모든 속성이 제거되고 하위에 선언한 인스턴스들 또한 모두 제거된다.

 

예제 코드를 살펴보자.

 

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
<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 !'
          },beforeCreate: function(){
            console.log("beforeCreate");
          },
          created: function(){
            console.log("created");
          },
          mounted: function(){
            console.log("mounted");
          },
          updated: function(){
            console.log("updated");
          }
        });
      </script>
  </body>
</html>
 
cs

 

위코드를 수행해보자. 어떠한 로그값이 출력될까? 한번 생각해보고 결과를 예측해보자. 

 

결과는 beforeCreate-created-mounted 만 출력될 것이고, updated는 출력되지 않을 것이다. 라이프 사이클 시작점에서 필자가 이야기 했던 부분이 있다. data가 변경되지 않으면 지나지 않는 라이프 사이클이 존재한다고 했는 데, 그 부분이 beforeUpdate, updated라는 라이프 사이클이다.

 

그렇다면 데이터를 변경하는 로직을 삽입해보자. 과연 updated라는 로그가 출력될까?

 

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
<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 !'
          },beforeCreate: function(){            
            console.log("beforeCreate");
          },
          created: function(){
            console.log("created");
          },
          mounted: function(){
            console.log("mounted");
            this.message="Hello Vue !?";
          },
          updated: function(){
            console.log("updated");
          }       
        });
      </script>
  </body>
</html>
 
cs

 mounted라는 라이프 사이클에서 message 데이터 값을 변경하였기 때문에 updated라는 라이프 사이클을 지나게 되므로 updated라는 로그가 출력되는 것을 볼 수 있다.

 

여기까지 뷰 인스턴스에 대해 간략히 다루어보았다. 다음 포스팅에서는 뷰 컴포넌트에 대한 포스팅을 진행할 것이다.

posted by 여성게
: