[Vue]라이프 사이클 알아보기
SW개발/Javascript

[Vue]라이프 사이클 알아보기

Vue 에서는 인스턴스나 컴포넌트가 생성될 때 라이프사이클(lifecycle) 이라고 정의된 몇 단계의 과정을 거친다.

즉, 인스턴스가 생성되면서 보여지고 사라지는 일련의 과정을 일컫는 말이다.

 

라이프 사이클은 Vue 공식 문서 에서 확인할 수 있다. 

 

Vue 라이프사이클

 

Vue 인스턴스는 다음과 같은 4가지의 과정을 거치면서 진행된다.

  • Create(생성)
  • Mount(부착)
  • Update(업데이트)
  • Destroy(제거)

이 각각의 단계에서 Vue Hook(훅)을 할 수 있도록 여러 개의 API를 제공한다. 아래와 같은 Hook이 존재한다.

  • beforeCreate, created
  • beforeMount, mounted
  • beforeUpdate, updated
  • beforeDestroy, destroyed

 

beforeCreate
var app = new Vue({
	el: '#app',
    data() {
    	return {
        	msg: 'hello leffe';
        }
    },
    beforeCreate(function() {
    	console.log(this.msg);
        // undefined 에러, this.$el에 접근할 수 없음
    })
})
        

가장 먼저 실행되는 beforeCreate 훅이다. Vue 인스턴스가 초기화 된 직후에 발생한다. 컴포넌트가 DOM에 추가되기 전이기 때문에 this.$el 에 접근할 수 없어, 위와 같이 사용하면 에러를 발생시키게 된다. (data, method 에도 접근 불가)

 

created
var app = new Vue({
	el: '#app',
    data() {
    	return {
        	msg: 'hello leffe';
        }
    },
    created(function() {
    	console.log(this.msg);
        // 접근 가능
    })
})
        

created 훅에서는 data를 반응형으로 추적할 수 있다. 따라서 computed, methods, watch 등이 활성화 되고 접근 할 수 있다.

하지만 DOM에는 추가되지 않은 상태이다.

data에 직접 접근이 가능하기 때문에, 컴포넌트 초기에 외부에서 받아온 값으로 data를 정하거나 event listener를 선언해야 할 경우 이 단계에서 하는 것이 바람직하다.

 

beforeMount
var app = new Vue({
	el: '#app',
    beforeMount(function() {
    	console.log('beforeMount, leffe');
    })
})
        

DOM에 부착되기 직전에 호출되는 beforeMount 훅이다. 이 훅이 일어나기 직전에 템플릿이 첫 렌더링 되기 때문에 가상 DOM이 생성은 되었으나, 실제 DOM에 부착되지는 않은 상태이다. 대부분의 경우 사용하지 않는다.

 

mounted
var app = new Vue({
	el: '#app',
    mounted(function() {
    	console.log('mounted, leffe');
    })
})
        

가상 DOM이 실제 DOM에 부착되고 난 후에 호출되는 mounted 훅이다. 따라서 this.$el, data, computed, methods, watch 등 모든 요소에 접근이 가능하다. 일반적으로 가장 많이 사용된다.

 

부모, 자식 관계의 훅 실행 순서

다만, 한 가지 유의할 점은 부모와 자식관계의 컴포넌트에서는 위의 사진과 같은 순서로 훅이 실행된다. 부모의 mounted 훅이 실행 되기 전, 자식의 mounted 훅이 먼저 실행된다.

 

var app = new Vue({
    el: '#app',
    mounted(function() {
        this.$nextTick(function() {
        	// 모든 화면이 렌더링된 후 실행됨
        })
    })
})

하지만 자식 컴포넌트가 서버에서 비동기로 데이터를 받아오는 경우에 부모의 mounted 훅은 자식 컴포넌트가 mounted 된 상태라는 것을 보장할 수는 없다. 따라서 this.$nextTick 을 활용하여 화면이 렌더링 된 이후에 실행되도록 하면 mounted 상태를 보장 받게 할 수 있다.

 

beforeUpdate
var app = new Vue({
    el: '#app',
    beforeUpdate(function() {
        console.log('beforeUpdate, leffe');
    })
})

컴포넌트에서 사용되는 data의 값이 변하면서 DOM에 변화를 적용 시켜야 할 때가 있다. 바로 그 변화 직전에 호출되는 것이 beforeUpdate 훅이다. (DOM이 재 렌더링되고 패치되기 직전에 실행됨)

이 훅에서 값들을 추가적으로 변화시키더라도 추가적인 렌더링이 이루어지지는 않는다. 

 

updated
var app = new Vue({
    el: '#app',
    updated(function() {
    	console.log('updated, leffe');
    })
})

재 렌더링이 일어난 후에 실행되는 updated 훅이다. 변경된 data 역시 DOM에 적용된 상태이다.

변경된 값들을 DOM을 이용해 접근하려고 한다면 upated 훅이 적절하다.

하지만, 이 훅에서 data를 변경하는 것은 무한 루프를 일으킬 수 있기 때문에 data를 직접 바꾸지 않아야 한다.

mounted 훅에서처럼 this.$nextTick 를 활용한다면 모든 화면이 업데이트 된 이후의 상태를 보장받을 수 있다.

 

beforeDestroy
var app = new Vue({
    el: '#app',
    beforeDestroy(function() {
        console.log('beforeDestroy, leffe');
    })
})

Vue 인스턴스가 제거되기 직전에 호출되는 beforeDestroy 훅이다. 아직 해체되기 전이기 때문에 인스턴스는 정상적으로 작동하여 모든 속성에 접근할 수 있다. 이 훅에서는 event listner를 해제하는 것 과 같은 일들을 주로 처리한다.

 

destroyed
var app = new Vue({
    el: '#app',
    destroyed(function() {
        console.log('destroyed, leffe');
    })
})

Vue 인스턴스가 제거되고 난 후에 호출되는 destroyed 훅이다. 제거가 된 이후이므로 인스턴스의 속성에 접근할 수 없고, 하위 Vue 인스턴스 또한 삭제된다.

 

개인적으로 공부를 하면서 정리한 내용이므로 틀린 내용이 있을 수 있습니다. 틀린내용을 댓글로 남겨주시면 감사하겠습니다 :)

 

728x90