Vue 3 e Keep alive
Source: Dev.to
Problema
Em uma tela com duas abas – Dúvidas (FAQ) e Formulário – o usuário perdia tudo que havia digitado no formulário ao mudar de aba. O componente do formulário era destruído e recriado, fazendo com que o estado fosse perdido.
Solução inicial (trabalhosa)
Salvar os dados a cada alteração no localStorage e limpar a chave ao submeter o formulário. Funciona, mas exige muito código manual e gerenciamento de estado externo.
Solução elegante com Vue
O Vue possui o componente <keep-alive> (embutido e abstrato). Ele não gera nenhum elemento HTML real; apenas instrui o Vue a cachear o componente em vez de destruí‑lo ao trocar de aba. Assim, o formulário e seus dados permanecem na memória com pouquíssimo esforço.
1️⃣ Página que recebe as abas
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;
}O
<keep-alive>envolve o componente dinâmico. No exemplo usamos abas, mas poderia ser qualquer componente.vue(até mesmo páginas).
2️⃣ Componente 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>Preencha seus dados</h2>
<p>Comece a digitar, troque de aba e volte. Seus dados estarão aqui!</p>
<div class="campo">
<label>Nome:</label>
<input v-model="formData.nome" type="text" />
</div>
<div class="campo">
<label>E‑mail:</label>
<input v-model="formData.email" type="email" />
</div>
<div class="campo">
<label>Mensagem:</label>
<textarea v-model="formData.mensagem"></textarea>
</div>
<button>Enviar</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;
}Ciclo de vida com <keep-alive>
| Hook | Quando é disparado |
|---|---|
onActivated | Depois que a instância do componente é inserida no DOM a partir do cache. |
onDeactivated | Depois que a instância do componente é removida do DOM e armazenada no cache. |
3️⃣ Componente 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;
}Conclusão
Usando <keep-alive> e os hooks onActivated / onDeactivated, conseguimos preservar o estado do formulário ao alternar entre abas, sem precisar de localStorage ou gerenciamento de estado externo. A implementação é curta, limpa e melhora significativamente a experiência do usuário.
Exit fullscreen mode
Cuidados com o keep-alive
Caso você precise carregar a página com reload, ele irá perder os dados, já que eles ficam guardados nos componentes em memória (cache).
Usamos o keep-alive no lado do cliente – ótimo em aplicações SPA.
Referência
- (nenhum item listado)