Front-End

[Vue.js] keep-alive로 캐시된 컴포넌트(페이지)를 reload 처리 하는 방법

특정 화면에 데이터를 추가해도 조회가 되지않는다는 오류가 있다고 하여 코드 분석을 시작하였다. 소스코드 분석하는 과정에서 어떤 메뉴는 클릭하면 클릭할 때 마다 백앤드 코드를 호출하여 매번 새롭게 조회를 하는가 하는 반면에 어떤 메뉴는 메뉴를 한번 클릭하면 처음에만 서버쪽 데이터(백앤드 코드)를 가져와서 조회를 하지만 그 이후 부터는 아무리 메뉴를 클릭해도 백앤드코드를 호출하지않고 있다. 처음엔 오류인가? 싶어서 몇 시간 삽질 끝에 소스문제는 아니다라는 결론에 도달 후 팀장에게 문의해본 후 알게되었다. keep-alive 기능을 사용한다는 것이다. 그렇게 keep-alive 관련 공부는 시작되었다. 

 

keep-alive에 의해 캐시된 컴포넌트는 vue.js의 기본 라이프사이클 훅이 호출되지 않는다. 라이프사이클 마다 로그를  찍어보면 확인할 수 있다. 

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Vue LifeCycle Sample</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
  </head>
  <body>
      <div id="logEx">
        {{msg}}
      </div>
      
      <script type="text/javascript">
        new Vue({
          el: '#logEx',
          data:{
            msg : 'Hello Vue.js!'
          },
          beforeCreate:function(){
            console.log("######## beforeCreate");
          },
          created:function(){
            console.log("######## created");
          },
          beforeMount:function(){
            console.log("######## beforeMount");
          },
          mounted:function(){
            console.log("######## mounted");
            //this.msg = "Complete mounted";
          },
          beforeUpdate:function(){
            console.log("######## beforeUpdate"); 
          }
          ,updated:function(){
            console.log("######## updated");
          }
          ,beforeDestory:function(){
          	console.log("######## beforeDestory");
          }          
          ,destoryed:function(){
          	console.log("######## destoryed");
          }
        });
      </script>
  </body>
</html>

 

keep-alive 코드스니펫

      <keep-alive :include="cacheList">
        <router-view :key="$route.fullPath" ref="eventBus" @onProgress="onProgress"></router-view>
      </keep-alive>
data: () => ({
    lm: {
      isShow: false,
      defList: [],
    },
    userName: null,
    cacheList: [
      'Feedback',       
      'Lib',
      'Segment',
    ],

    favority: {
      isShow: false,
      isShowSetPopup: false,
      list: [],
      setList: [],
    },
    progressIsShow: false,
    loginDialogIsShow: false,
  }),

keep-alive의 대상이 되는 컴포넌트를 include를 사용하여 조건부로 캐시할 수 있습니다. 

 

keep-alive를 사용하는 동적 컴포넌트

  • keep-alive를 사용하는 이유는 주로 컴포넌트 상태를 유지하거나 다시 렌더링되는 것을 방지하기 위해서 사용된다.
  • 콤포넌트가 keep-alive 내에서 전환되면, activated()와 deactivated() 라이프사이클 훅이 호출된다.
  • 컴포넌트가 destory 되지않기 때문에 destory() 라이프사이클 훅이 호출되지 않는다. 
  • vue.js 2.5.0+ 이후로 max를 사용해 최대 컴포넌트 캐시 개수를 지정할 수 있습니다. 최대 개수가 넘어가면 가장 최근에 사용되어 캐시된 컴포넌트부터 파괴한다.

 

라이프사이클 훅 : activated

  • keep-alive 컴포넌트가 활성화될 때 호출됩니다.
  • 이 훅은 서버측 렌더링 중 호출되지 않습니다.

 

라이프사이클 훅 : deactivated

  • keep-alive 컴포넌트가 비활성화될 때 호출됩니다.
  • 이 훅은 서버측 렌더링 중 호출되지 않습니다.

 

 

주의사항

<keep-alive>는 캐시할 인스턴스가 없기 때문에, 함수형 컴포넌트와 함께 작동하지 않습니다.

 

 

그렇다면, keep-alive를 사용하여 캐시된 컴포넌트에 대한 reload는 어떻게 처리해야할까? 방법은 의외로 간단하다.

  activated() {
    console.log('########## MyLib activated()');
    this.searchBookLib();
  },

 

 

[관련 자료]

 

동적 & 비동기 컴포넌트 | Vue.js

동적 & 비동기 컴포넌트 이 페이지는 여러분이 이미 컴포넌트 기초를 읽었다고 가정하고 쓴 내용입니다. 컴포넌트가 처음이라면 기초 문서를 먼저 읽으시기 바랍니다. keep-alive를 사용하는 동적

v3.ko.vuejs.org

 

 

Render Functions & JSX — Vue.js

Vue.js – 프로그레시브 자바스크립트 프레임워크

kr.vuejs.org

 

[참고]

 

Leave a Reply

error: Content is protected !!