Vue.js, Vue3 - Life Cycle(라이프 사이클)

김화영·2024년 7월 5일
0

Vue3

목록 보기
2/14
post-thumbnail

!! 듣고있는 강의에서는 Vue2를 사용하기 때문에 정보가 혼동될 수 있음 주의, 최대한 찾아가면서 하는중 ㅠㅠ

인스턴스 라이프사이클 훅

각 Vue 인스턴스는 생성될 때, 일련의 초기화 단계를거친다. Vue의 컴포넌트가 생성되고 소멸될 때 까지의 다양한 단계에서 특정 로직을 실행하도록 할 수 있는 다양한 메소드들로 개발자는 이 라이프사이클 동안 발생하는 이벤트에 대응하여 로직을 실행할 수 있다.

이미지 출처: https://ko.vuejs.org/guide/essentials/lifecycle#lifecycle-diagram

라이프사이클 훅설명
beforeCreate인스턴스가 생성되고 반응성 속성이 설정되기 전에 호출
정의해 놓은 데이터가 제대로 동작되지 않는 상태
created인스턴스가 생성되고 반응성 속성이 설정된 후에 호출
일반적인 옵션들의 체크를 진행 후 mount(연결/부착) 훅으로 넘어감
beforeMount인스턴스가 마운트 되기 직전에 호출
Vue에서는 html의 동작에 대해서는 아직 모름 DOM이 연결되기 직전이기 때문에 el연결 안됨
mounted인스턴스가 마운트(연결/부착)된 직후에 호출
beforeUpdate데이터가 변경되어 가상 DOM이 다시 렌더링 되기 전에 호출
화면에 그려지기 직전의 개념
updated가상 DOM이 다시 렌더링 된 후에 호출
beforeUnmount(vue2-beforeDestroy)인스턴스가 해제되기 전에 호출
인스턴스를 더이상 필요로 하지 않을 때 실행 뷰인스턴스.$destroy()라는 메소드가 호출될 때, 인스턴스가 없어지기 직전
unmounted(vue3-destroyed)인스턴스가 해제된 후에 호출
뷰 인스턴스가 완전히 증발하는 건 아니고 watch, child components, event listeners가 모두 파괴 그래서 인스턴스 내에 있는 variable도 사용하지 못한다고 뜬다.

라이프사이클 훅 실습 예제

1. 라이프 사이클 훅이 제대로 실행되는지 확인하기.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <div>{{ msg }}</div>
    </div>

    <script>
        const vm = new Vue({
            el: '#app',
            data:{
                msg:'Hello Vue!'
            }, 
            /* Vue 라이프사이클 훅은 생애주기 순서대로 진행되기 때문에, 
            순서를 뒤죽박죽 해놓아도 정해진 순서대로 콘솔창에 나타나게 된다. */
            beforeCreate () {
                console.log('beforeCreate!', )
            },
            created () {
                console.log('created!')
            },
            beforeMount (){
                console.log('beforeMount!')
            },
            mounted () {
                console.log('mounted!')
            }
        })
    </script>
</body>
</html>

2. beforeCreate부터 mounted까지

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <div>{{ msg }}</div>
        <div ref="div"></div> <!-- div라는 이름의 요소를 참조하겟다.-->
    </div>

    <script>
        const vm = new Vue({
            el: '#app',
            data:{
                msg:'Hello Vue!'
            },
            beforeCreate () {
                console.log('beforeCreate!', this.msg)
            },
            created () {
                console.log('created!', this.msg)
            },
            beforeMount (){
                console.log('beforeMount!', this.$refs.div) // ref안에 있는 div라는 요소를 참조하겠다.
            },
            mounted () {
                console.log('mounted!', this.$refs.div)
            }
        })
    </script>
</body>
</html>

위의 콘솔창을 통해 DOM에 연결되기 전과 후의 상황을 확인 할 수 있다. mounted가 된 후에야 div라는 요소가 특정되기 때문에 콘솔창에 해당 요소를 출력할 수 있는 것이다.

3. updated

아래 이미지처럼 beforeUpdate, updated를 써도 변경된 데이터가 없기 때문에 콘솔창에서는 실행되지 않는 것을 볼 수 있다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <div ref="msg">{{ msg }}</div>
        <div ref="div"></div>
    </div>

    <script>
        const vm = new Vue({
            el: '#app',
            data:{
                 msg:'Hello Vue!'
            }, 
            beforeCreate () {
                console.log('beforeCreate!', this.msg)
            },
            created () {
                console.log('created!', this.msg)
            },
            beforeMount (){
                console.log('beforeMount!', this.$refs.div)
            },
            mounted () {
                console.log('mounted!', this.$refs.div)
            },
            beforeUpdate () { // 데이터가 변경될 때에만 실행된다.
                console.log('beforeUpdate!', this.$refs.msg.innerText)
            }, 
            updated () {
                console.log('updated!')
            }
        })
    </script>
</body>
</html>

위의 코드에서 {{ msg }}가 쓰여있는 div에 ref="msg"라는 속성을 추가해주고, 콘솔창에서 데이터를 직접 변경해주면 아래와 같은 내용이 실행된다.

beforeUpdate는 화면에 업데이트 되기 전의 innerText를 표기하게 됨을 볼 수 있다.

4. unmounted

언마운트에서 자꾸 오류가 나는데 이유를 모르겠다... Vue2에서는 인스턴스.$destroy()를 호출하여 beforeDestroy와 destroyed 훅을 실행하지만, Vue3에서는 인스턴스.unmount()를 호출하여 beforeUnmount, unmounted 훅을 실행한다고한다. 나머지는 잘 작동되는데, unmount() 메소드만 호출하면 자꾸 없는 funtion이라는 오류가 뜬다.. 구글링에도 chatGPT도 해결하지 못한오류 대체 무엇일까!!!!!! 나중에 다시 알아보자


Vue3 라이프 사이클 훅 (options)

찾아보니 Vue에서는 options와 composition에서 사용하는 훅이 달랐다. 어떻게 셋팅하느냐의 차이인 것 같은데, 스크립트에서 setup() {}으로 옵션을 설정하면 composition인 듯 하다..? 이건 강의가아니라 따로 찾아봐야하는 문법인듯?

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
    <div id="app">
        <div ref="msg">{{ msg }}</div>
        <div ref="div"></div> <!-- div라는 이름의 요소를 참조하겟다.-->
    </div>

    <script>
        const App = {
            data() {
                return {
                    msg:'Hello Vue!'
                };
            }, 
            /* Vue 라이프사이클 훅은 생애주기 순서대로 진행되기 때문에, 
            순서를 뒤죽박죽 해놓아도 정해진 순서대로 콘솔창에 나타나게 된다. */
            beforeCreate () {
                console.log('beforeCreate!', this.msg)
            },
            created () {
                console.log('created!', this.msg)
            },
            beforeMount (){
                console.log('beforeMount!', this.$refs.div) // ref안에 있는 div라는 요소를 참조하겠다.
            },
            mounted () {
                console.log('mounted!', this.$refs.div)
            },
            beforeUpdate () { // 데이터가 변경될 때에만 실행된다.
                console.log('beforeUpdate!', this.$refs.msg.innerText)
            }, 
            updated () {
                console.log('updated!')
            },
            beforeUnmount () { // 인스턴스 해제
                console.log('beforeUnmount!')
            },
            unmounted () {
                console.log('unmounted!')
            }
        };

        const app = Vue.createApp(App).mount('#app')

        const unmount = () => {
            app.unmount()
        }
    </script>
</body>
</html>
profile
백엔드 개발자 주주주니어

0개의 댓글