Capítulo 1 de 11

Tutorial VueJS 3 – Criar uma aplicação Vue com create-vue

verificado a 7 Setembro 2026 · 5 min

Resposta rápida

Cria o projeto com npm create vue@latest, responde «não» ao TypeScript e corre npm install e npm run dev. Uma aplicação Vue nasce de createApp(App).mount('#app'), um dado declarado com ref() aparece no template entre chavetas duplas e atualiza-se sozinho.

No fim deste capítulo, vais ter um projeto Vue 3 a funcionar e vais saber mostrar um dado reativo no ecrã.

Uma aplicação Vue é uma instância criada por createApp e ligada a um elemento da página. Este capítulo instala o projeto e mostra um primeiro dado no ecrã.

Criar o projeto

O Vue tem um gerador oficial, create-vue, que monta um projeto Vite já configurado para Vue. Abre um terminal na pasta onde guardas os teus projetos:

bash
npm create vue@latest

O gerador faz uma série de perguntas. Para este tutorial, responde:

  • Project name: boutique-vue
  • TypeScript: Não, ficamos em JavaScript para não misturar duas aprendizagens.
  • JSX, Vue Router, Pinia, ESLint, Prettier: Não. Acrescentamo-los quando forem úteis.
  • Vitest: Sim se quiseres escrever testes, caso contrário Não.
Cuidado com a opção –default

Muitos tutoriais indicam npm create vue@latest -- --default para «ir depressa». No create-vue 3.23, esta flag ativa o TypeScript: ficas com um src/main.ts e ficheiros tsconfig, que não é o que queres aqui. Responde antes às perguntas.

Instala as dependências e arranca o servidor de desenvolvimento:

npm install falha com o npm do Node 22

No Node 22, o npm fornecido (10.9) para com npm error Cannot read properties of null (reading 'edgesOut'), tanto num projeto novo como no código deste tutorial. Atualize o npm antes de instalar: npm install -g npm@latest. O Node 24 não tem este problema.

bash
cd boutique-vue
npm install
npm run dev

O Vite mostra um endereço, normalmente http://localhost:5173/. Abre-o: aparece a página inicial do projeto.

O que o gerador criou

bash
boutique-vue/
├── index.html          ← la seule vraie page HTML du site
├── package.json
├── vite.config.js
├── public/             ← fichiers servis tels quels
└── src/
    ├── main.js         ← point d’entrée : crée et monte l’application
    ├── App.vue         ← composant racine
    ├── assets/
    └── components/

Três ficheiros contam por agora. O gerador cria também src/assets/main.css e base.css, o estilo da sua página inicial: poderá apagá-los, juntamente com a linha import './assets/main.css' que abre src/main.js, quando o CSS do tutorial os substituir no fim do capítulo.

O index.html tem um contentor vazio e carrega o ponto de entrada. É tudo: o resto da página vai ser produzido pelo Vue.

index.html
<body>
  <div id="app"></div>
  <script type="module" src="/src/main.js"></script>
</body>

O src/main.js cria a aplicação a partir do componente raiz e monta-a nesse contentor.

src/main.js
import './assets/main.css'

import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

createApp(App) constrói a instância, .mount('#app') dá-lhe o elemento do DOM que tem direito a gerir. A partir daí, tudo o que está dentro de <div id="app"> pertence ao Vue.

O primeiro componente

Um ficheiro .vue é um componente de ficheiro único: o script, o template e o estilo do mesmo pedaço de interface vivem no mesmo sítio. Esvazia o src/App.vue e escreve:

src/App.vue
<script setup>
import { ref } from 'vue'

const product = ref('T-Shirt')
</script>

<template>
  <div class="product-display">
    <h1>{{ product }}</h1>
  </div>
</template>

Grava: o browser mostra «T-Shirt» sem recarregar a página. É a substituição de módulos a quente do Vite.

Este ficheiro vai crescer até ao capítulo sobre os componentes, onde o vamos dividir.

Perceber estas sete linhas

<script setup> indica ao Vue que este bloco descreve a lógica do componente. Tudo o que declaras no primeiro nível fica utilizável no template, sem exportar seja o que for.

ref('T-Shirt') cria uma referência reativa: uma caixa que guarda um valor e avisa o Vue quando ele muda. No script, abre-se a caixa com .value:

javascript
const product = ref('T-Shirt')

console.log(product.value)   // 'T-Shirt'
product.value = 'Pull'       // o título muda imediatamente no ecrã

No template, pelo contrário, escreve-se {{ product }} sem .value: o Vue desembrulha a referência automaticamente.

As chavetas duplas são uma interpolação. Aceitam qualquer expressão JavaScript, não apenas um nome de variável:

html
<h1>{{ product }}</h1>
<h1>{{ product.toUpperCase() }}</h1>
<h1>{{ 'Notre ' + product }}</h1>

A reatividade, na prática

Muda o valor inicial para 'Pull' e grava: o título acompanha. Não escreveste uma única linha para ir buscar o h1 e alterar o seu conteúdo. É este o cerne do Vue: descreves o que a página deve mostrar em função do estado e o Vue trata da atualização.

Na Options API

O mesmo componente escrever-se-ia export default { data() { return { product: 'T-Shirt' } } }, e o script chegaria ao valor por this.product. Com <script setup>, this não existe: só há variáveis.

E as outras ferramentas de build?

O create-vue instala o Vite, a ferramenta recomendada pela equipa do Vue. Há outros bundlers que também compilam ficheiros .vue: o Parcel através de @parcel/transformer-vue, ou o webpack com o vue-loader.

Funcionam, mas são mais lentos e saem do caminho batido. Medido a 2 de setembro de 2026 na mesma aplicação de um só componente:

bash
Vite 8.2.2     build en  1,05 s   →  60,57 kB  (23,91 kB gzip)
Parcel 2.16.4  build en 10,57 s   →  92,77 kB

O resultado de npm run build é uma pasta de ficheiros estáticos. O que ela contém decide o teu posicionamento nos motores de busca, assunto tratado à parte.

Num projeto novo, fica-te pelo Vite. As alternativas só se justificam se a tua cadeia de build atual já depender delas.

O CSS do tutorial

Para que a aplicação tenha algum aspeto, cria o src/assets/boutique.css com as poucas regras usadas ao longo dos capítulos:

src/assets/boutique.css
.product-display { display: flex; gap: 32px; padding: 24px; font-family: system-ui, sans-serif; }
.product-image img { width: 240px; }
.variants-wrapper { display: flex; gap: 10px; }
.color-circle { width: 50px; height: 50px; margin-top: 8px; border: 2px solid #d8d8d8; border-radius: 50%; cursor: pointer; }
.button { border: none; background: #1d4ed8; color: #fff; padding: 10px 18px; border-radius: 6px; cursor: pointer; }
.disabledButton { background-color: #d8d8d8; cursor: not-allowed; }

E importa-o no ponto de entrada:

src/main.js
import './assets/boutique.css'
import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')
ExercícioAcrescenta um dado brand com o valor «Gekkode» e mostra-o no título, antes do nome do produto. Depois muda-lhe o valor no código e confirma que a página se atualiza sem recarregar.

Erros frequentes

npm create vue@latest -- --default instala o TypeScript No create-vue 3.23, a flag --default ativa o TypeScript: ficas com um src/main.ts e ficheiros tsconfig. Corre o comando sem flag e responde «não» à pergunta sobre TypeScript.
Esquecer o .value no script ref() devolve um objeto. No script, escreve product.value, no template, {{ product }} chega, o Vue desembrulha a referência.
Uma versão do Node demasiado antiga O create-vue exige Node 22.18 ou superior. Confirma com node -v antes de criar o projeto.
Newsletter

Os novos testes, tutoriais e projetos, por e-mail.

Testes reproduzíveis, código versionado, resultados datados. Nunca spam.