ABOUT ME

Today
Yesterday
Total
  • Vue.js 3의 mount 와 생명주기
    Vue.js 2024. 7. 28. 16:55

    회사에서 처음으로 화면개발 업무를 맡았고 vue3를 이용해 개발해야 했습니다. 다른 팀은 차세대 프로젝트를 진행하고 있었고 제가 소속된 팀은 그중에 작은 부분을 맡게 되었습니다. 팀이 다르다 보니 개발 가이드에 대한 접근 권한이 없었고 개발 중인 소스만을 파악해 화면과 서버 API를 개발했어야 했습니다.

     

    처음에는 복붙으로 기본적인 개발은 끝냈으나 테스트 도중 다양한 버그를 만났고 그 버그를 수정하려고 보니 데이터를 언제 뿌려줘야 할까라는 고민이 들었습니다. 제가 마주한 문제 중 하나는 '팝업 실행 후 데이터를 지우고 오른쪽 상단의 엑스를 누르고 나갔을 때, 데이터가 삭제되지 않았으나 다시 팝업을 열었을 때 공란이 발생하는 것'이었습니다. 

     

    처음 시도했던 방법은 watch를 통해 데이터를 재호출하는 것이었습니다. 하지만 데이터상의 실질적인 변화는 없었고 화면에서 보여지는 변화만 있었기에 watch가 원하는 시점에 작동하지 않았습니다. 따라서  해당 문제를 해결하기 위해  vue가 어떻게 작동하는지 등 vue의 라이프 사이클에 대한 지식의 필요성을 느꼈습니다.

     

     

     

    vue3 공식 문서 속 라이프 사이클은 이렇게 설명되어 있습니다.

    여기서 '마운트'될 때 데이터를 다시 불러와 넣어주면 되겠다싶어 mounted를 활용해 해당 데이터의 API를 다시 호출했습니다. 결과적으로 버그는 수정되었지만 마운트 라는 의미가 도대체 뭘까 라는 생각이 들었습니다. 회사에서 진행하는 프로젝트의 경우 보안상의 이유로 공개할 수 없어 인강으로 만들었던 todo 서비스 코드와 책을 통해 공부해 보았습니다.

     

     

    이번 인강을 듣고 실제 업무에서 개발을 해보니 프로젝트의 구조를 알고 개발하는 것의 중요성을 다시금 느꼈습니다. 우선 public > index.html 파일이 있고 src > App.vue, src > main.js 라는 파일이 있습니다. 사실상 이 파일들의 소스를 보면 존재의 이유가 체감되지 않았는데요. 공부를 해보니 이 부분들이 Vue의 시작점이며 없어서는 안 될 것이라는 점을 알게 되었습니다.

     

     

    - src > main.js

    import { createApp } from 'vue'
    import App from './App.vue'
    import router from './router'
    import store from './store'
    
    createApp(App).use(store).use(router).mount('#app')

    모든 Vue 앱은 main.js의 createApp 함수를 이용해 앱 인스턴스를 생성하는 것으로 시작합니다. 여기서 .mount() 메서드를 통해 렌더링이 시작됩니다.

     

     

    - public > index.html 

    <!DOCTYPE html>
    <html lang="">
      <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <link rel="icon" href="<%= BASE_URL %>favicon.ico">
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
        <title><%= htmlWebpackPlugin.options.title %></title>
      </head>
      <body>
        <noscript>
          <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
        </noscript>
        <div id="app"></div>
        <div id="modal"></div>
        <!-- built files will be auto injected -->
      </body>
    </html>

    루트 템플릿인 index.html에서 어떤 요소를 어떻게 배치할지 결정을 해야 합니다. <body> 부분에 app이라는 선택자를 사용해 요소를 넣어줬고 배치할 요소와 애플리케이션을 연결하는 것이 바로 마운트라고 합니다.

     

     

    - src > App.vue

    <template>
      
      <Navbar />
    
      <div class="container">
        <router-view/>
      </div>
    
      <Toast />
    
    </template>
    
    <script>
    import Toast from '@/components/Toast.vue';
    import Navbar from '@/components/Navbar.vue';
    
    export default {
      components: {
        Toast,
        Navbar,
      },
      setup() {
        
      }
    }
    </script>
    
    <style scoped>
    .slide-enter-active,
      .slide-leave-active {
        transition: all 0.5s ease;
      }
    
      .slide-enter-from,
      .slide-leave-to {
        opacity: 0;
        transform: translateY(-30px);
      }
    
      .slide-enter-to,
      .slide-leave-from {
        opacity: 1;
        transform: translateY(0px);
      }
    </style>

    그리고 app.vue의 해당 코드가 실행되는 것입니다. 따라서 마운트 시점에 맞게 데이터를 다시 호출했을 때 비효율적일 수 있지만 해당 버그는 수정되었음을 확인할 수 있었습니다.

    728x90
Designed by Tistory.