# Introdução
NOTA
Conhece o Vue 2 e só quer ver o que há de novo no Vue 3? Confira o Guia de Migração!
# O que é Vue.js?
Vue (pronuncia-se /vjuː/, como view, em inglês) é um framework progressivo para a construção de interfaces de usuário. Ao contrário de outros frameworks monolíticos, Vue foi projetado desde sua concepção para ser adotável incrementalmente. A biblioteca principal é focada exclusivamente na camada visual (view layer), sendo fácil adotar e integrar com outras bibliotecas ou projetos existentes. Por outro lado, Vue também é perfeitamente capaz de dar poder a sofisticadas Single-Page Applications quando usado em conjunto com ferramentas modernas e bibliotecas de apoio (opens new window).
Se você gostaria de saber mais sobre Vue antes de mergulhar nele, nós criamos um vídeo (em inglês) passeando pelos princípios básicos e um exemplo de projeto.
# Primeiros Passos
DICA
O guia oficial supõe um nível intermediário em HTML, CSS e JavaScript. Se você é totalmente novo no mundo do frontend, mergulhar diretamente em um framework pode não ser a melhor ideia para começar - compreenda primeiro o básico e depois volte! Experiência anterior com outros frameworks ajuda, mas não é obrigatória.
A forma mais simples de testar o Vue é usando o exemplo de Olá Mundo (opens new window). Sinta-se à vontade para abrí-lo em outra aba e acompanhar conosco durante os próximos exemplos básicos.
A página Instalação deste guia oferece mais opções para instalar o Vue. Nota: nós não recomendamos que iniciantes comecem com o vue-cli
, especialmente se você não está familiarizado com ferramentas de build baseadas em Node.js.
# Renderização Declarativa
No núcleo do Vue está um sistema que nos permite declarativamente renderizar dados no DOM (Document Object Model) usando uma sintaxe de template simples:
<div id="counter">
Contador: {{ counter }}
</div>
2
3
const Counter = {
data() {
return {
counter: 0
}
}
}
Vue.createApp(Counter).mount('#counter')
2
3
4
5
6
7
8
9
Acabamos de criar nosso primeiro aplicativo Vue! Isso parece muito similar a renderizar uma template string, mas o Vue fez bastante trabalho interno. Os dados e o DOM estão agora interligados e tudo se tornou reativo. Como podemos ter certeza? Dê uma olhada no exemplo a seguir, onde a propriedade counter
incrementa a cada segundo, e você verá como o DOM renderizado muda:
const CounterApp = {
data() {
return {
counter: 0
}
},
mounted() {
setInterval(() => {
this.counter++
}, 1000)
}
}
2
3
4
5
6
7
8
9
10
11
12
Contador: 0
Além de simples interpolação de texto, podemos interligar atributos de elementos:
<div id="bind-attribute">
<span v-bind:title="message">
Pare o mouse sobre mim e veja a dica interligada dinamicamente!
</span>
</div>
2
3
4
5
const AttributeBinding = {
data() {
return {
message: 'Você carregou esta página em ' + new Date().toLocaleString()
}
}
}
Vue.createApp(AttributeBinding).mount('#bind-attribute')
2
3
4
5
6
7
8
9
See the Pen Interligação dinâmica de atributos by Vue (@Vue) on CodePen.
Aqui nos deparamos com algo novo. O atributo v-bind
que você está vendo é chamado de diretiva. Diretivas são prefixadas com v-
para indicar que são atributos especiais providos pelo Vue, e como você deve ter percebido, aplicam comportamento especial de reatividade ao DOM renderizado. Neste caso, basicamente estamos dizendo: "mantenha o atributo title
do elemento sempre atualizado em relação à propriedade message
da instância atualmente ativa".
# Tratando Interação do Usuário
Para permitir aos usuários interagir com o aplicativo, podemos usar a diretiva v-on
para anexar escutas a eventos (event listeners) que invocam métodos em nossas instâncias:
<div id="event-handling">
<p>{{ message }}</p>
<button v-on:click="reverseMessage">Inverter Mensagem</button>
</div>
2
3
4
const EventHandling = {
data() {
return {
message: 'Olá Vue.js!'
}
},
methods: {
reverseMessage() {
this.message = this.message
.split('')
.reverse()
.join('')
}
}
}
Vue.createApp(EventHandling).mount('#event-handling')
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
See the Pen Escutas em eventos by Vue (@Vue) on CodePen.
Observe que neste método atualizamos o estado da aplicação sem tocar no DOM - todas as manipulações são tratadas pelo Vue e o código que você escreve é focado na lógica de manipulação de dados.
Vue também provê a diretiva v-model
, que torna a interligação de mão dupla (two-way binding) entre a caixa de texto e o estado da aplicação uma moleza:
<div id="two-way-binding">
<p>{{ message }}</p>
<input v-model="message" />
</div>
2
3
4
const TwoWayBinding = {
data() {
return {
message: 'Olá Vue.js!'
}
}
}
Vue.createApp(TwoWayBinding).mount('#two-way-binding')
2
3
4
5
6
7
8
9
See the Pen Interligação de mão dupla by Vue (@Vue) on CodePen.
# Condicionais e Repetições
Também é fácil alternar a presença de um elemento:
<div id="conditional-rendering">
<span v-if="seen">Agora você me viu</span>
</div>
2
3
const ConditionalRendering = {
data() {
return {
seen: true
}
}
}
Vue.createApp(ConditionalRendering).mount('#conditional-rendering')
2
3
4
5
6
7
8
9
Este exemplo demonstra que nós podemos interligar dados não apenas ao texto e aos atributos, mas também à estrutura do DOM. Mais do que isso, Vue também provê um poderoso sistema de transições que pode automaticamente aplicar efeitos de transição quando elementos são inseridos/atualizados/removidos pelo Vue.
Você pode alterar seen
de true
para false
no exemplo abaixo para ver em ação:
See the Pen Renderização condicional by Vue (@Vue) on CodePen.
Existem mais algumas diretivas, cada uma com sua própria funcionalidade. Por exemplo, a diretiva v-for
pode ser usada para exibir uma lista de itens usando dados de um Array:
<div id="list-rendering">
<ol>
<li v-for="todo in todos">
{{ todo.text }}
</li>
</ol>
</div>
2
3
4
5
6
7
const ListRendering = {
data() {
return {
todos: [
{ text: 'Aprender JavaScript' },
{ text: 'Aprender Vue' },
{ text: 'Criar algo incrível' }
]
}
}
}
Vue.createApp(ListRendering).mount('#list-rendering')
2
3
4
5
6
7
8
9
10
11
12
13
See the Pen Renderização de listas by Vue (@Vue) on CodePen.
# Composição com Componentes
O sistema de componentes também é outro importante conceito no Vue, por ser uma abstração que proporciona a construção de aplicações de larga escala compostas por pequenos componentes, auto-contidos e frequentemente reutilizáveis. Se nós pensarmos sobre isso, quase qualquer tipo de interface de uma aplicação pode ser abstraída em uma árvore de componentes:
No Vue, um componente é essencialmente uma instância com opções pré-definidas. Registrar um componente no Vue é trivial: criamos um objeto para o componente assim como fizemos com os objetos App
e o utilizamos na opção components
de seu elemento pai:
// Cria uma aplicação Vue
const app = Vue.createApp(...)
// Define um novo componente chamado todo-item
app.component('todo-item', {
template: `<li>Isto é uma tarefa</li>`
})
// Monta a aplicação Vue
app.mount(...)
2
3
4
5
6
7
8
9
10
Agora você pode compor com ele no template de outro componente:
<ol>
<!-- Cria uma instância do componente todo-item -->
<todo-item></todo-item>
</ol>
2
3
4
Mas isto renderizaria o mesmo texto toda vez que um item fosse utilizado, o que não é lá muito interessante. Devemos poder passar os dados do escopo superior (parent) para os componentes filhos. Vamos modificar o componente para fazê-lo aceitar uma prop:
app.component('todo-item', {
props: ['todo'],
template: `<li>{{ todo.text }}</li>`
})
2
3
4
Agora podemos passar o dado todo
em cada repetição de componente usando v-bind
:
<div id="todo-list-app">
<ol>
<!--
Agora provemos cada todo-item com o objeto todo que ele
representa, de forma que seu conteúdo possa ser dinâmico.
Também precisamos prover cada componente com uma "chave",
a qual será explicada posteriormente.
-->
<todo-item
v-for="item in groceryList"
v-bind:todo="item"
v-bind:key="item.id"
></todo-item>
</ol>
</div>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const TodoList = {
data() {
return {
groceryList: [
{ id: 0, text: 'Vegetais' },
{ id: 1, text: 'Queijo' },
{ id: 2, text: 'Qualquer outra coisa que humanos podem comer' }
]
}
}
}
const app = Vue.createApp(TodoList)
app.component('todo-item', {
props: ['todo'],
template: `<li>{{ todo.text }}</li>`
})
app.mount('#todo-list-app')
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
See the Pen Introdução a componentes by Vue (@Vue) on CodePen.
Este é um exemplo fictício, mas conseguimos separar nossa aplicação em duas pequenas unidades, sendo que o componente filho está razoavelmente bem desacoplado do componente pai graças à funcionalidade de props
. Podemos agora melhorar nosso componente <todo-item>
com template e lógica mais complexos, sem afetar o restante.
Em uma aplicação grande, é essencial dividir todo o aplicativo em componentes para tornar o desenvolvimento gerenciável. Falaremos mais sobre componentes futuramente neste guia, mas aqui está um exemplo (imaginário) da aparência que o template de um aplicativo poderia ter com o uso de componentes:
<div id="app">
<app-nav></app-nav>
<app-view>
<app-sidebar></app-sidebar>
<app-content></app-content>
</app-view>
</div>
2
3
4
5
6
7
# Relação com Elementos Customizados
Você pode ter notado que componentes Vue são similares aos Elementos Customizados, parte da Especificação de Web Components (opens new window). Isto ocorre pois a sintaxe de componentes Vue foi vagamente modelada a partir da especificação. Por exemplo, implementamos a Slot API (opens new window) e o atributo especial is
. Entretanto, existem algumas diferenças fundamentais:
- A Especificação de Web Components foi finalizada, mas não está nativamente implementada em todos os navegadores. O Safari 10.1+, Chrome 54+ e Firefox 63+ suportam nativamente os componentes da Web. Em comparação, componentes Vue funcionam consistentemente em todos os navegadores suportados (IE11 com o build de compatibilidade e superiores). Quando necessário, componentes Vue também podem ser envolvidos dentro de um elemento customizado nativo.
- Componentes Vue oferecem importantes recursos não disponíveis em elementos customizados tradicionais, mais notavelmente: fluxo de dados entre componentes, comunicação com eventos customizados e integração com ferramentas de build.
Embora o Vue não use elementos personalizados internamente, há ótima interoperabilidade (opens new window) quando se trata de consumir ou distribuir como elementos personalizados. O Vue CLI também suporta a criação de componentes Vue que se registram como elementos personalizados nativos.
# Pronto para Mais?
Nós introduzimos brevemente os recursos mais básicos do núcleo do Vue - o resto deste guia se aprofundará neles e em outros recursos avançados em um nível muito maior de detalhes, portanto certifique-se de ler tudo!