🧩 Exercícios Práticos: Comunicação com defineProps, defineEmits e defineModel

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


🎯 Nível 1: Fundamentos

Problema 05.1 — Declaração de Props com defineProps e Tipagem Estrita

Contexto: Declaração de Props com defineProps e Tipagem Estrita no contexto de Comunicação com defineProps, defineEmits e defineModel.

Requisitos de Execução:

  1. Criar componente BotaoCustom.vue aceitando props texto: string e variante?: 'primario' | 'secundario'.

Resultado Esperado

Props tipadas e validadas em tempo de compilação com TypeScript.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_05_1_SeuNome
  2. Envie na tarefa: Atividade Cap 05 - Comunicação com defineProps, defineEmits e defineModel
🔑 Gabarito de Código & Solução Comentada
<!-- BotaoCustom.vue -->
<script setup lang="ts">
interface Props {
  texto: string;
  variante?: 'primario' | 'secundario';
  desabilitado?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  variante: 'primario',
  desabilitado: false,
});
</script>

<template>
  <button :class="`btn-${props.variante}`" :disabled="props.desabilitado">
    {{ props.texto }}
  </button>
</template>

🔍 Nível 2: Prática

Problema 05.2 — Emissão de Eventos Customizados com defineEmits

Contexto: Emissão de Eventos Customizados com defineEmits no contexto de Comunicação com defineProps, defineEmits e defineModel.

Requisitos de Execução:

  1. Emitir evento @salvar passando objeto com ID e dados validados via emit('salvar', payload).

Resultado Esperado

Evento customizado emitido para o componente pai.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_05_2_SeuNome
  2. Envie na tarefa: Atividade Cap 05 - Comunicação com defineProps, defineEmits e defineModel
🔑 Gabarito de Código & Solução Comentada
<!-- FormEmissor.vue -->
<script setup lang="ts">
const emit = defineEmits<{
  (e: 'salvar', dados: { id: number; nome: string }): void;
  (e: 'cancelar'): void;
}>();

const confirmar = () => {
  emit('salvar', { id: 10, nome: 'Novo Item' });
};
</script>

<template>
  <button @click="confirmar">Confirmar</button>
</template>

⚡ Nível 3: Integração

Problema 05.3 — Two-Way Binding Moderno com defineModel() no Vue 3.4+

Contexto: Two-Way Binding Moderno com defineModel() no Vue 3.4+ no contexto de Comunicação com defineProps, defineEmits e defineModel.

Requisitos de Execução:

  1. Criar componente de input reutilizável utilizando macro const model = defineModel<string>().

Resultado Esperado

Sincronização bidirecional simplificada sem emit('update:modelValue').

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_05_3_SeuNome
  2. Envie na tarefa: Atividade Cap 05 - Comunicação com defineProps, defineEmits e defineModel
🔑 Gabarito de Código & Solução Comentada
<!-- InputReutilizavel.vue -->
<script setup lang="ts">
const model = defineModel<string>({ required: true });
</script>

<template>
  <input v-model="model" class="border p-2 rounded" />
</template>

🏆 Nível 4: Desafio Corporativo

Problema 05.4 — Múltiplos v-models e Modificadores Customizados

Contexto: Múltiplos v-models e Modificadores Customizados no contexto de Comunicação com defineProps, defineEmits e defineModel.

Requisitos de Execução:

  1. Criar componente aceitando v-model:primeiroNome e v-model:sobrenome com modificador .capitalizar.

Resultado Esperado

Múltiplos modelos bidirecionais sincronizados no mesmo componente.

📤 Instruções de Entrega (Microsoft Teams)

  1. Salve o arquivo como: Atividade_05_4_SeuNome
  2. Envie na tarefa: Atividade Cap 05 - Comunicação com defineProps, defineEmits e defineModel
🔑 Gabarito de Código & Solução Comentada
<!-- NomeCompletoModel.vue -->
<script setup lang="ts">
const [primeiro, primeiroModifiers] = defineModel('primeiroNome', {
  set(val: string) { return primeiroModifiers.capitalizar ? val.toUpperCase() : val; }
});
const sobrenome = defineModel('sobrenome');
</script>