Prof. Me. Danilo Bueno
ref()
computed()
onMounted()
fetch
<script setup> let contador = 0; function incrementar() { contador++; // Vue não vê essa mudança } </script> <template> <p>{{ contador }}</p> <button @click="incrementar">+1</button> </template>
A tela nunca atualiza. O Vue precisa de uma forma de observar o valor.
<script setup> import { ref } from "vue"; const contador = ref(0); function incrementar() { contador.value++; // .value no script } </script> <template> <p>{{ contador }}</p> <!-- sem .value no template --> <button @click="incrementar">+1</button> </template>
.value é obrigatório no script — o Vue desempacota automaticamente no template.
.value
const nome = ref("Ana"); // string const ativo = ref(false); // boolean const itens = ref([]); // array const produto = ref(null); // começa vazio
Use ref() como padrão. Funciona com qualquer valor.
import { ref, computed } from "vue"; const produtos = ref([]); const totalProdutos = computed(() => produtos.value.length); const totalEmPromocao = computed(() => { let contador = 0; for (const p of produtos.value) { if (p.promocao) contador++; } return contador; });
Recalcula só quando produtos muda. Resultado é cacheado.
produtos
computed
// computed — cachea o resultado, só recalcula quando muda const totalProdutos = computed(() => produtos.value.length); // método — recalcula a cada re-renderização function getTotalProdutos() { return produtos.value.length; }
Use computed quando o valor depende de estado reativo.
onMounted executa uma vez, logo após o componente aparecer na tela. É o lugar certo para buscar dados de uma API.
onMounted
<script setup> import { ref, onMounted } from "vue"; const musicas = ref([]); onMounted(async () => { const res = await fetch("https://api.exemplo.com/musicas"); musicas.value = await res.json(); }); </script>
Cliente e servidor trocam dados por HTTP — normalmente em JSON.
Em REST, operamos sobre recursos (produtos, usuários, pedidos...). A intenção vem de método + URL.
GET
GET /products
POST
POST /products
PUT/PATCH
PUT /products/10
DELETE
DELETE /products/10
método URL ↓ ↓ POST /products Headers: { Content-Type: application/json } Body: { "nome": "Teclado", "preco": 199.9 }
Resposta da API:
Status: 201 Created Body: { "id": 42, "nome": "Teclado", "preco": 199.9 }
JSON.stringify
O body de uma requisição HTTP é texto. JSON.stringify converte o objeto antes de enviar.
body
const produto = { nome: "Teclado", preco: 199.9, emEstoque: true }; console.log(produto); // { nome: 'Teclado', preco: 199.9, emEstoque: true } console.log(JSON.stringify(produto)); // '{"nome":"Teclado","preco":199.9,"emEstoque":true}'
Na resposta, res.json() faz o caminho inverso — texto JSON → objeto JS.
res.json()
async function criarProduto(produto) { const res = await fetch("https://api.exemplo.com/products", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(produto), }); if (!res.ok) throw new Error("Erro ao criar produto"); const criado = await res.json(); itens.value.push(criado); // atualiza estado local }
Após o POST: adicione o retorno ao array com push. Não refaz o GET.
push
async function removerProduto(id) { const res = await fetch(`https://api.exemplo.com/products/${id}`, { method: "DELETE", }); if (!res.ok) throw new Error("Erro ao remover"); }
@submit.prevent
JavaScript puro (já visto antes):
form.addEventListener("submit", (event) => { event.preventDefault(); // impede reload da página salvar(); });
No Vue, é a mesma coisa com sintaxe mais curta:
<form @submit.prevent="salvar">
.prevent é atalho para event.preventDefault().
.prevent
event.preventDefault()
ref(valor)
computed(() => ...)
onMounted(() => ...)
JSON.stringify(obj)