[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공식 가이드 문서
https://v3.ko.vuejs.org/api/built-in-components.html#keep-alive - https://v3.ko.vuejs.org/api/options-lifecycle-hooks.html#deactivated
- https://v3.ko.vuejs.org/api/options-lifecycle-hooks.html#activated