개발 일기

[Vue.js 시작하기] - 라이프사이클 본문

Vue.js

[Vue.js 시작하기] - 라이프사이클

윤지 2021. 1. 12. 22:33

라이프사이클이란?

인스턴트나 컴포넌트가 생성되고 사라지기 까지에 몇 단계를 거치게 된다.

이는 미리 정의 되어있으며 우리 눈에 보여지고 사라지기 까지의 단계를 일컫는 말이라고 생각하면 쉽다.

위는 라이프사이클 다이어그램을 뜻한다.

라이프사이클은 크게 4단계로 나누면

1. 인스턴스의 생성 (create)

2. 생성된 인스턴스를 화면에 부착 (mount)

3. 화면에 부착된 인스턴스의 내용 갱신 (update)

4. 인스턴스가 소멸 (destory)

로 분류할 수 있다. 라이프사이클은 위의 4단계의 전후를 합쳐서 총 8개로 되어있다.

 

8단계의 라이프사이클 설명과 주요 라이프사이클은 예제를 통해서 사용 예시를 보도록하겠다.

 

beforeCreate

먼저 beforeCreate는 인스턴스가 생성되고 나서 가장 처음 실행된다.

인스턴스 초기화 직후에 발생된다고 생각하면 될 것이다.

 

이때는 data, method 속성이 아직 정의되지 않아서 Dom의 data 및 method에 접근할 수 없다.

<script>
export default {
  data: function () {
    return {
      value: "vuejs 입문하기",
    };
  },
  beforeCreate() {
    console.log("beforeCreate");
    console.log(this.value); // undefined
  },
};
</script>

위의 예제에서 data를 콘솔에 찍어보았을때 undefined 가 찍히는걸 확인할 수 있었다.

 

Created

이벤트버스를 사용하여 컴포넌트끼리 데이터를 전달한다는 것을 안다면 익숙할 라이프 사이클이다.

(컴포넌트 데이터 전달 방법을 모른다면 참고 : 2021/01/11 - [Vue.js] - Vue.js 시작하기 - 컴포넌트 데이터 전달 방법 )

 

created 훅에는 data를 추적하는 것이 가능할 뿐 아니라 props, methods, computed, watch가 활성화되어 접근이 가능하다. 하지만, 아직까지 Dom에 추가되지 않은 상태이다.

 

그렇지만 data에 직접 접근 가능하다는 점에서 컴포넌트 초기에 외부에서 받아온 값들을 data로 세팅해야 할 때

이 단계에서 하는 것이 가장 적절하다.

<script>
import { eventBus } from "@/main.js";
export default {
  props: ["propsValue"],
  data: function () {
    return {
      value: "vuejs 입문하기",
      initValue: null,
    };
  },
  created() {
    console.log("created");
    console.log(this.value); // vuejs 입문하기

    eventBus.$on("sendValue", (value) => {
      console.log(value);
    }); //이벤트 받기

    this.initValue = this.propsValue;
    // props value를 data에 정의
  },
};
</script>

위의 예제에서 beforeCreate 때와 다르게 콘솔에 찍힌 data의 값이 정의해둔대로 잘 나오는 것을 확인할 수 있다.

또한, 컴포넌트 생성과 동시에 이벤트를 받는 것을 등록하여 종료하기 전까지는 등록해둔 이벤트를 계속 받고

초기에 props 값으로 data 세팅하는 것도 확인할 수 있었다.

 

beforeMount

Dom에 부착하기 직전에 호출된다. 쉽게 말해 가상 Dom은 이미 생성이 되어있으나, 실제 Dom에는 아직 부착되지

않은 상태라고 할 수 있다. 이 단계에서는 render 함수가 호출되기 직전의 로직을 추가하면 좋다.

여기에서 render 함수는 자바스크립트로 화면에 Dom을 그리는 함수를 뜻한다.

 

mounted

가상 Dom의 내용이 실제 Dom에 부착된 이후에 실행되는 훅이기 때문에 $el을 사용하여 실제 Dom에 접근할 수 있다.

이는 화면 요소를 제어하는 로직을 수행하기 좋은 단계라고 생각하면 쉬울 것 같다.

 

하지만 mounted 훅이 호출되었다고 모든 컴포넌트가 마운트 되었다고 할 수는 없다. 전체 렌더링이 된 상태에서 작업을 진행하기 위해서는 $nextTick을 사용하면 된다. 

 

<template>
  <div>
    {{ this.title }}
    <ul>
      <li>{{ this.subjectOne }}</li>
      <li>{{ this.subjectTwo }}</li>
    </ul>
  </div>
</template>

<script>
import { eventBus } from "@/main.js";
export default {
  data: function () {
    return {
      title: "vuejs 공부하기",
      subjectOne: "라이프사이클",
      subjectTwo: "이벤트버스",
    };
  },
  mounted() {
    this.$nextTick(() => {
      // 모든 화면이 렌더링된 후 호출

      console.log("mounted");
      console.log(this.$el);
      /*<div>vuejs 공부하기 <ul><li>라이프사이클</li> <li>이벤트버스</li></ul></div>*/
    });
  },
};
</script>

위의 예제의 mounted 훅에서는 모든 화면이 렌더링된 후 this.$el을 콘솔에 출력하여 실제 Dom에 부착된 것을 확인할 수 있었다.

beforeUpdate

컴포넌트에서 사용되는 data의 값이 변경되면 컴포넌트가 재랜더링을 하게 되는데, 그때 가상 DOM으로 화면을 다시 그리기 전에 호출되는 단계다. 실제 Dom에 변화를 적용시켜야 할 때, 그 변화 직전에 호출되기 때문에 렌더링을 추가로 호출하지는 않는다.

 

updated

가상 DOM을 렌더링 하고 실제 DOM이 변경된 이후에 호출되는 단계이다. 한마디로 데이터가 변경되고 나서 가상 Dom으로 다시 화면을 그리고 나면 실행되는 단계다. 만약 변경된 값들을 가진 Dom을 이용해 접근하고 싶다면 이 때가 가장 적절하다. updated 훅에서 data를 수정하게 되면 또 update 훅이 호출 되기 때문에 무한 루프에 빠질 수 있으니 주의해야한다.

 

beforeDestroy

인스턴스가 소멸되기 직전에 호출되는 단계다. 이 단계에서는 이벤트 리스너를 해체하거나 이벤트 버스를 off 하는 등

인스턴스가 사라지기 전에 해야할 일들을 처리하는 것이 좋다. 아직 인스턴스에 접근할 수 있기 때문에 뷰 인스턴스의 데이터를 삭제해야한다면 삭제할 수 있다.

<script>
import { eventBus } from "@/main.js";
export default {
  data: function () {
    return {
      ctrlKey: false,
    };
  },
  created() {
    eventBus.$on("sendValue", (value) => {
      console.log(value);
    }); //이벤트버스 받기
  },
  mounted() {
    document.addEventListener("keydown", this.watchCtrlKeyDown);
    //key 이벤트리스너 등록 => watchCtrlKeyDown 함수 호출
  },
  beforeDestroy() {
    document.removeEventListener("keydown", this.watchCtrlKeyDown);
    //key에 대한 이벤트리스너 해지

    eventBus.$off("sendValue"); //등록한 이벤트버스 없앰
  },
  methods: {
    //ctrl 키를 감시하는 method
    watchCtrlKeyDown(event) {
      let key = window.event ? window.event.keyCode : event.keyCode;
      switch (key) {
        case 17:
          this.ctrlKey = true;
          break;
      }
    },
  },
};
</script>

위의 예제에서는 created 훅 때 등록해둔 이벤트 버스를 beforeDestroy 훅에서 해지하였고,

document에 등록된 이벤트 리스너 또한 beforeDestroy 훅에서 해지하였다. 

destroyed

말 그대로 인스턴스가 소멸된 이후에 호출되는 단계다. 속성에 접근할 수 없으며 만약 하위 컴포넌트를 가지고 있다면

그것또한 제거된다.

 

 

 

라이프사이클을 완벽히 이해한 후, 프로젝트를 진행한다면 순차적으로 머리속에서 정리가 되는 느낌이라 로직을 짜는데 큰 도움이 되는 것 같다. 

Comments