Vue 3에서 Keep alive
Source: Dev.to
위의 링크에 있는 전체 글을 번역해 주시면 됩니다.
(코드 블록, URL, 마크다운 구문 및 기술 용어는 그대로 유지하고, 본문 텍스트만 한국어로 번역해 주세요.)
문제
두 개의 탭이 있는 화면 – **Dúvidas (FAQ)**와 Formulário – 에서 사용자는 탭을 전환할 때 폼에 입력한 모든 내용을 잃어버렸습니다. 폼 컴포넌트가 파괴되고 다시 생성되어 상태가 사라졌습니다.
초기 솔루션 (번거로운)
localStorage의 변경마다 데이터를 저장하고, 폼을 제출할 때 키를 삭제합니다. 작동하지만 많은 수동 코드와 외부 상태 관리가 필요합니다.
Vue를 사용한 우아한 솔루션
Vue에는 <keep-alive> 컴포넌트가 있습니다(내장 및 추상). 이 컴포넌트는 실제 HTML 요소를 생성하지 않으며, 탭을 전환할 때 컴포넌트를 파괴하는 대신 캐시하도록 Vue에 지시합니다. 따라서 폼과 그 데이터가 최소한의 노력으로 메모리에 유지됩니다.
1️⃣ 탭을 받는 페이지
import { shallowRef } from "vue";
import AbaFormulario from "../components/AbaFormulario.vue";
import AbaDuvidas from "../components/AbaDuvidas.vue";
const abaAtual = shallowRef(AbaFormulario);<div class="botoes-abas">
<button @click="abaAtual = AbaFormulario" :class="{ ativo: abaAtual === AbaFormulario }">
Preencher Formulário
</button>
<button @click="abaAtual = AbaDuvidas" :class="{ ativo: abaAtual === AbaDuvidas }">
Dúvidas Frequentes
</button>
</div>
<keep-alive>
<component :is="abaAtual" />
</keep-alive>.ativo {
font-weight: bold;
background-color: #e0e0e0;
color: var(--black);
}
.botoes-abas {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
<keep-alive>는 동적 컴포넌트를 감싸줍니다. 예시에서는 탭을 사용했지만, 어떤.vue컴포넌트든 (심지어 페이지도) 사용할 수 있습니다.
2️⃣ 컴포넌트 AbaFormulario
<script setup>
import { ref, onActivated, onDeactivated } from "vue";
const formData = ref({
nome: "",
email: "",
mensagem: "",
});
onActivated(() => {
console.log("Formulário ATIVADO (Recuperado do cache)");
});
onDeactivated(() => {
console.log("Formulário DESATIVADO (Guardado no cache)");
});
</script>
<template>
<div class="formulario-container">
<h2>데이터를 입력하세요</h2>
<p>타이핑을 시작하고, 탭을 바꾼 뒤 다시 돌아오세요. 입력한 데이터가 여기 남아 있습니다!</p>
<div class="campo">
<label>이름:</label>
<input v-model="formData.nome" type="text" />
</div>
<div class="campo">
<label>이메일:</label>
<input v-model="formData.email" type="email" />
</div>
<div class="campo">
<label>메시지:</label>
<textarea v-model="formData.mensagem"></textarea>
</div>
<button>보내기</button>
</div>
</template>.formulario-container {
padding: 20px;
border: 1px solid #ccc;
border-radius: 8px;
}
.campo {
margin-bottom: 15px;
display: flex;
flex-direction: column;
}
input,
textarea {
padding: 8px;
margin-top: 5px;
border: 1px solid #999;
border-radius: 4px;
}
button {
padding: 10px 15px;
background-color: #4caf50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}<keep-alive>와 함께하는 라이프사이클
| 후크 | 언제 트리거되는가 |
|---|---|
onActivated | 컴포넌트 인스턴스가 캐시에서 DOM에 삽입된 후. |
onDeactivated | 컴포넌트 인스턴스가 DOM에서 제거되고 캐시에 저장된 후. |
3️⃣ 컴포넌트 AbaDuvidas
<template>
<div class="duvidas-container">
<h2>Dúvidas Frequentes (FAQ)</h2>
<p>Aqui estão as respostas para as perguntas mais comuns.</p>
<div class="faq-item">
<h3>Preciso preencher todos os campos do formulário?</h3>
<p>Sim, todos os campos são obrigatórios para que possamos entrar em contato de forma eficiente.</p>
</div>
<div class="faq-item">
<h3>Qual o prazo de resposta?</h3>
<p>Nossa equipe geralmente responde em até 24 horas úteis.</p>
</div>
</div>
</template>.duvidas-container {
padding: 20px;
border: 1px solid #ccc;
border-radius: 8px;
background-color: var(--black);
}
.faq-item {
margin-top: 15px;
padding-bottom: 10px;
border-bottom: 1px dashed #ccc;
}
h3 {
margin-bottom: 5px;
color: var(--white);
font-size: 1.1em;
}결론
<keep-alive>와 onActivated / onDeactivated 훅을 사용하면, 탭을 전환할 때 폼의 상태를 보존할 수 있으며, localStorage나 외부 상태 관리가 필요하지 않습니다. 구현은 짧고 깔끔하며 사용자 경험을 크게 향상시킵니다.
전체 화면 모드 종료
keep-alive에 대한 주의사항
페이지를 reload로 다시 로드해야 할 경우, 데이터가 손실됩니다. 데이터는 메모리(캐시) 내 컴포넌트에 저장되어 있기 때문입니다.
keep-alive를 클라이언트 측에서 사용합니다 – SPA 애플리케이션에 매우 좋습니다.
참고
- (목록 없음)