Vue 3 e Keep alive

Published: (March 12, 2026 at 07:32 AM EDT)
4 min read
Source: Dev.to

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>

HookQuando é disparado
onActivatedDepois que a instância do componente é inserida no DOM a partir do cache.
onDeactivatedDepois 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)
0 views
Back to Blog

Related posts

Read more »