O que é Vue?
Vue é um framework JavaScript progressivo para a construção de interfaces de usuário. A palavra é deliberada: você pode adicionar Vue a uma única página para aprimorar um widget, ou utilizá-lo com uma ferramenta de build para criar uma aplicação completa. Não é necessário reescrever nada para obter valor, e o framework cresce conforme as suas necessidades.
Em sua essência, o Vue consiste em duas coisas: uma sintaxe de template que estende o HTML e um sistema de reatividade que rastreia seus dados e atualiza a view automaticamente. Você declara o que a UI deve exibir, e o Vue a mantém sincronizada.
Single-file components
Um componente Vue geralmente reside em um arquivo .vue com três blocos: um template, um script e estilos. Mantê-los juntos torna o componente uma unidade única e autocontida.
<!-- Card.vue -->
<script setup>
defineProps({ title: String });
</script>
<template>
<article class="card">
<h3>{{ title }}</h3>
<slot />
</article>
</template>
<style scoped>
.card {
border-radius: 1rem;
padding: 1.5rem;
}
</style>
O <style scoped> limita automaticamente o CSS a este componente, evitando que os nomes das classes vazem para fora. O <script setup> é uma macro de compilador que torna a Composition API concisa e é o padrão moderno.
Sintaxe de template
Os templates do Vue são HTML com um pequeno conjunto de diretivas. A interpolação utiliza chaves duplas, e as diretivas são atributos prefixados com v-.
<!-- profile.vue -->
<template>
<h1>{{ user.name }}</h1>
<p v-if="user.online">Online</p>
<p v-else>Offline</p>
<ul>
<li v-for="post in posts" :key="post.id">
{{ post.title }}
</li>
</ul>
<img :src="user.avatar" :alt="user.name" />
<button @click="follow">Follow</button>
</template>
Leia as abreviações da seguinte forma: :src vincula um atributo a uma expressão, e @click escuta um evento. v-if renderiza condicionalmente, e v-for cria loops com um :key para atualizações eficientes. O template é compilado em funções de renderização, mas raramente você precisará vê-las.
Reatividade: ref e reactive
O sistema de reatividade do Vue monitora seus dados e renderiza novamente a interface quando eles mudam. Na Composition API, você cria valores reativos com ref ou reactive.
<script setup>
import { ref, reactive } from "vue";
const count = ref(0); // .value in script
const user = reactive({ // proxy, no .value
name: "Ada",
online: true,
});
function increment() {
count.value += 1;
}
</script>
O ref envolve qualquer valor e é acessado através de .value no script, embora os templates façam o “unwrap” automaticamente para você. O reactive retorna um proxy profundamente reativo para um objeto. Uma convenção comum é utilizar ref consistentemente, já que ele funciona para tipos primitivos e é fácil de reatribuir.
Computed e watch
Duas funções lidam com valores derivados e efeitos colaterais.
<script setup>
import { ref, computed, watch } from "vue";
const items = ref([10, 20, 30]);
const total = computed(() =>
items.value.reduce((sum, n) => sum + n, 0),
);
watch(items, (next, prev) => {
console.log("items changed", prev, next);
});
</script>
computed faz o cache do seu resultado e recalcula apenas quando uma dependência muda — use-o sempre que um valor for derivado de outro estado. watch executa um callback quando uma fonte muda e serve para efeitos colaterais, como logging, fetch ou salvamento. Tentar usar watch para computar um valor é um erro comum.
Props, emits e slots
Os dados fluem para baixo através de props e para cima através de eventos emitidos.
<!-- Child.vue -->
<script setup>
const props = defineProps({
label: { type: String, required: true },
});
const emit = defineEmits(["select"]);
function handleClick() {
emit("select", props.label);
}
</script>
<template>
<button @click="handleClick">{{ label }}</button>
</template>
<!-- Parent.vue -->
<Child label="Save" @select="onSelect" />
As props são somente leitura no componente filho, o que mantém a fonte da verdade no componente pai. Slots permitem que um pai passe marcação para um filho, o equivalente ao children do React.
Composables
A maior vantagem da Composition API é a lógica reutilizável. Um composable é uma função que utiliza reatividade e retorna estado, nomeada com o prefixo use.
// useFetch.js
import { ref, watchEffect } from "vue";
export function useFetch(url) {
const data = ref(null);
const error = ref(null);
watchEffect(async () => {
data.value = null;
error.value = null;
try {
const res = await fetch(url.value);
data.value = await res.json();
} catch (err) {
error.value = err;
}
});
return { data, error };
}
Composables compartilham lógica, não estado, portanto, cada componente que chama useFetch recebe seus próprios dados independentes. Este é o equivalente do Vue para um custom hook.
Roteamento e estado
O Vue Router gerencia a navegação com um mapeamento declarativo de URL para componente, e o Pinia é a store oficial para estado compartilhado.
// router.js
import { createRouter, createWebHistory } from "vue-router";
export const router = createRouter({
history: createWebHistory(),
routes: [
{ path: "/", component: Home },
{ path: "/users/:id", component: UserProfile },
],
});
Utilize uma store quando diversos componentes distantes precisarem do mesmo estado. Para dados locais ou entre pai e filho, props e composables geralmente são suficientes.
Melhores práticas
- Use
script setupe a Composition API para códigos novos. - Prefira
computedem vez dewatchpara valores derivados. - Mantenha as props como somente leitura e emita eventos para alterações.
- Extraia a lógica reutilizável para composables.
- Use estilos
scopedou CSS Modules para manter os estilos locais. - Nomeie composables com o prefixo
use. - Evite acessar o estado de componentes filhos; comunique-se através de props e emits.
Erros comuns
- Esquecer o
.valueem uma ref dentro do script. - Usar
watchpara calcular um valor que ocomputeddeveria derivar. - Mutar props em um componente filho em vez de emitir um evento.
- Desestruturar um objeto
reactivee perder a reatividade. - Colocar todo o estado em uma store global quando o estado local seria suficiente.
- Misturar a Options API e a Composition API sem um motivo claro.
Próximos passos
O Vue é uma porta de entrada suave para frameworks de componentes e escala para qualquer tamanho de projeto. Adicione o Nuxt para renderização no servidor e convenções de roteamento, compare a abordagem com React e Svelte, e mantenha seu JavaScript afiado. Depois, construa algo pequeno — como uma lista filtrável ou um formulário com validação — e deixe a reatividade fazer o trabalho pesado.