🧩 Exercícios Práticos: Formulários e Validação com Vee-Validate e Zod

Spec Frontend Com Vue • Trilha Progressiva em 4 Níveis


🎯 Nível 1: Fundamentos

Problema 10.1 — Formulário com useForm e toTypedSchema do Zod

Contexto: Formulário com useForm e toTypedSchema do Zod no contexto de Formulários e Validação com Vee-Validate e Zod.

Requisitos de Execução:

  1. Conectar schema Zod ao Vee-Validate utilizando toTypedSchema(schema).

Resultado Esperado

Formulário validado com integração Zod e Vee-Validate.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_10_1_SeuNome
  2. Envie na tarefa: Atividade Cap 10 - Formulários e Validação com Vee-Validate e Zod
🔑 Gabarito de Código & Solução Comentada
<!-- FormVeeZod.vue -->
<script setup lang="ts">
import { useForm } from 'vee-validate';
import { toTypedSchema } from '@vee-validate/zod';
import { z } from 'zod';

const schema = toTypedSchema(z.object({
  email: z.string().email('E-mail inválido'),
  senha: z.string().min(6, 'Mínimo 6 caracteres'),
}));

const { defineField, handleSubmit, errors } = useForm({ validationSchema: schema });
const [email, emailProps] = defineField('email');
const [senha, senhaProps] = defineField('senha');

const onSubmit = handleSubmit((values) => console.log('Dados:', values));
</script>

<template>
  <form @submit="onSubmit">
    <input v-model="email" v-bind="emailProps" placeholder="Email" />
    <span>{{ errors.email }}</span>
    <button type="submit">Entrar</button>
  </form>
</template>

🔍 Nível 2: Prática

Problema 10.2 — Componente Field com Exibição de ErrorMessage

Contexto: Componente Field com Exibição de ErrorMessage no contexto de Formulários e Validação com Vee-Validate e Zod.

Requisitos de Execução:

  1. Criar campos declarativos usando <Field name='nome' /> e <ErrorMessage name='nome' />.

Resultado Esperado

Mensagem de erro exibida automaticamente no blur do campo.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_10_2_SeuNome
  2. Envie na tarefa: Atividade Cap 10 - Formulários e Validação com Vee-Validate e Zod
🔑 Gabarito de Código & Solução Comentada
<!-- FormDeclarativo.vue -->
<script setup lang="ts">
import { Form, Field, ErrorMessage } from 'vee-validate';
</script>

<template>
  <Form @submit="console.log">
    <Field name="nome" rules="required" />
    <ErrorMessage name="nome" class="text-red-500" />
  </Form>
</template>

⚡ Nível 3: Integração

Problema 10.3 — Reset de Formulário e Estados isSubmitting / isDirty

Contexto: Reset de Formulário e Estados isSubmitting / isDirty no contexto de Formulários e Validação com Vee-Validate e Zod.

Requisitos de Execução:

  1. Desabilitar botão durante envio com isSubmitting e resetar formulário após confirmação.

Resultado Esperado

Feedback de envio e limpeza automática dos campos após submissão bem-sucedida.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_10_3_SeuNome
  2. Envie na tarefa: Atividade Cap 10 - Formulários e Validação com Vee-Validate e Zod
🔑 Gabarito de Código & Solução Comentada
<!-- FormSubmitState.vue -->
<script setup lang="ts">
import { useForm } from 'vee-validate';

const { handleSubmit, isSubmitting, resetForm } = useForm();
const salvar = handleSubmit(async (val) => {
  await new Promise(r => setTimeout(r, 1000));
  resetForm();
});
</script>

🏆 Nível 4: Desafio Corporativo

Problema 10.4 — Validação Assíncrona de Unicidade no Backend com Zod .refine()

Contexto: Validação Assíncrona de Unicidade no Backend com Zod .refine() no contexto de Formulários e Validação com Vee-Validate e Zod.

Requisitos de Execução:

  1. Validar se o e-mail já existe no banco disparando consulta assíncrona no schema Zod.

Resultado Esperado

Validação assíncrona de e-mail existente executada em tempo real.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_10_4_SeuNome
  2. Envie na tarefa: Atividade Cap 10 - Formulários e Validação com Vee-Validate e Zod
🔑 Gabarito de Código & Solução Comentada
// asyncUserSchema.ts
import { z } from 'zod';

export const userSchemaAsync = z.object({
  email: z.string().email().refine(async (email) => {
    const res = await fetch(`/api/checar-email?email=${email}`);
    const { disponivel } = await res.json();
    return disponivel;
  }, 'Este e-mail já está em uso'),
});