Guia
Essenciais
- Instalação
- Introdução
- A Instância Vue
- Sintaxe de Templates
- Dados Computados e Observadores
- Interligações de Classe e Estilo
- Renderização Condicional
- Renderização de Listas
- Manipulação de Eventos
- Interligações em Formulários
- Básico sobre Componentes
Componentes em Detalhes
- Registro de Componentes
- Propriedades
- Eventos Personalizados
- Slots
- Dinâmicos & Assíncronos
- Lidando com Casos Extremos
Transições & Animações
- Transições de Visibilidade e Listas
- Transições de Estado
Reuso & Composição
- Mixins
- Diretivas Personalizadas
- Funções de Renderização & JSX
- Plugins
- Filtros
Ferramentas
- Componentes Single-File
- Testes Unitários
- Testing
- Suporte ao TypeScript
- Publicando em Produção
Escalonando
- Roteamento
- Gerenciamento de Estado
- Renderizando no Lado do Servidor
- Segurança
Internamente
- Reatividade em Profundidade
Migração
- Migração do Vue 1.x
- Migração do Vue Router 0.7.x
- Migração do Vuex 0.6.x para 1.0
Diversos
- Comparação com Outros Frameworks
- Junte-se à Comunidade Vue.js!
- Conheça a Equipe
Você está navegando a documentação da v2.x e anterior. Para a v3.x, clique aqui.
Transições de Estado
O sistema de transição do Vue oferece muitas maneiras simples de animar entradas, saídas e listas, mas e quanto à animação de seus próprios dados? Por exemplo:
- números e cálculos
- cores exibidas
- as posições de nós SVG
- os tamanhos e outras propriedades de elementos
Todos estes já estão armazenados como números brutos ou podem ser convertidos em números. Uma vez que fazemos isso, nós podemos animar estas mudanças de estado usando bibliotecas de terceiros, em combinação com os sistemas de reatividade e componente do Vue.
Animando Estado com Observadores
Observadores nos permitem animar mudanças de qualquer propriedade numérica para outra propriedade. Isso pode parecer complicado no começo, por isso vamos mergulhar em um exemplo usando GreenSock:
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.2.4/gsap.min.js"></script>
<div id="animated-number-demo">
<input v-model.number="number" type="number" step="20">
<p>{{ animatedNumber }}</p>
</div>
new Vue({
el: '#animated-number-demo',
data: {
number: 0,
tweenedNumber: 0
},
computed: {
animatedNumber: function() {
return this.tweenedNumber.toFixed(0);
}
},
watch: {
number: function(newValue) {
gsap.to(this.$data, { duration: 0.5, tweenedNumber: newValue });
}
}
})
{{ animatedNumber }}
Quando você atualiza o número, a mudança é animada abaixo do input. Isto produz uma demonstração agradável, mas o que acontece com o que não é diretamente gravado como um número, como qualquer cor CSS válida por exemplo? Veja como podemos conseguir isso com Tween.js e Color.js:
<script src="https://cdn.jsdelivr.net/npm/tween.js@16.3.4"></script>
<script src="https://cdn.jsdelivr.net/npm/color-js@1.0.3"></script>
<div id="example-7">
<input
v-model="colorQuery"
v-on:keyup.enter="updateColor"
placeholder="Informe uma cor"
>
<button v-on:click="updateColor">Atualizar</button>
<p>Visualização:</p>
<span
v-bind:style="{ backgroundColor: tweenedCSSColor }"
class="example-7-color-preview"
></span>
<p>{{ tweenedCSSColor }}</p>
</div>
var Color = net.brehaut.Color
new Vue({
el: '#example-7',
data: {
colorQuery: '',
color: {
red: 0,
green: 0,
blue: 0,
alpha: 1
},
tweenedColor: {}
},
created: function () {
this.tweenedColor = Object.assign({}, this.color)
},
watch: {
color: function () {
function animate () {
if (TWEEN.update()) {
requestAnimationFrame(animate)
}
}
new TWEEN.Tween(this.tweenedColor)
.to(this.color, 750)
.start()
animate()
}
},
computed: {
tweenedCSSColor: function () {
return new Color({
red: this.tweenedColor.red,
green: this.tweenedColor.green,
blue: this.tweenedColor.blue,
alpha: this.tweenedColor.alpha
}).toCSS()
}
},
methods: {
updateColor: function () {
this.color = new Color(this.colorQuery).toRGB()
this.colorQuery = ''
}
}
})
.example-7-color-preview {
display: inline-block;
width: 50px;
height: 50px;
}
Visualização:
{{ tweenedCSSColor }}
Transições de Estado Dinâmicas
Tal como acontece com os componentes de transição do Vue, as transições de estado de suporte de dados podem ser atualizadas em tempo real, o que é especialmente útil para prototipação! Mesmo usando um polígono SVG simples, você pode obter muitos efeitos que seriam difíceis de imaginar até que você tenha brincado um pouco com as variáveis.
Veja este demo para o código completo por detrás do exemplo acima.
Organizando Transições em Componentes
Gerenciar muitas transições de estado pode aumentar rapidamente a complexidade de uma instância ou componente Vue. Por sorte, muitas animações podem ser extraídas para componentes filho separados. Vamos fazer isso com o inteiro animado de nosso exemplo anterior:
<script src="https://cdn.jsdelivr.net/npm/tween.js@16.3.4"></script>
<div id="example-8">
<input v-model.number="firstNumber" type="number" step="20"> +
<input v-model.number="secondNumber" type="number" step="20"> =
{{ result }}
<p>
<animated-integer v-bind:value="firstNumber"></animated-integer> +
<animated-integer v-bind:value="secondNumber"></animated-integer> =
<animated-integer v-bind:value="result"></animated-integer>
</p>
</div>
// Esta lógica tweening complexa agora pode ser reusada por
// quaisquer inteiros que desejemos animar em nossa aplicação.
// Componentes também oferecem uma interface clara para configurar
// transições mais dinâmicas e estratégias de transição mais
// complexas.
Vue.component('animated-integer', {
template: '<span>{{ tweeningValue }}</span>',
props: {
value: {
type: Number,
required: true
}
},
data: function () {
return {
tweeningValue: 0
}
},
watch: {
value: function (newValue, oldValue) {
this.tween(oldValue, newValue)
}
},
mounted: function () {
this.tween(0, this.value)
},
methods: {
tween: function (startValue, endValue) {
var vm = this
function animate () {
if (TWEEN.update()) {
requestAnimationFrame(animate)
}
}
new TWEEN.Tween({ tweeningValue: startValue })
.to({ tweeningValue: endValue }, 500)
.onUpdate(function () {
vm.tweeningValue = this.tweeningValue.toFixed(0)
})
.start()
animate()
}
}
})
// Toda a complexidade foi agora removida da instância principal do Vue!
new Vue({
el: '#example-8',
data: {
firstNumber: 20,
secondNumber: 40
},
computed: {
result: function () {
return this.firstNumber + this.secondNumber
}
}
})
Dentro de componentes filho nós podemos usar qualquer combinação das estratégias de transição que foram apresentadas nesta página, juntamente com aquelas oferecidas pelo sistema de transição integrado do Vue. Juntos, há poucos limites para o que pode ser realizado.
Trazendo Desenhos à Vida
Animar, por definição, significa trazer à vida. Infelizmente, quando designers criam ícones, logos e mascotes, eles geralmente os entregam como imagens ou SVGs estáticos. Embora o gato-polvo do GitHub, o pássaro do Twitter e muitos outros logos se assemelhem a criaturas vivas, eles não parecem estar realmente vivos.
Vue pode ajudar. Como SVGs são apenas dados, nós só precisamos de exemplos do que essas criaturas se parecem quando estão animadas, pensativas ou alertas. Então Vue pode ajudar na transição entre estes estados, tornando suas páginas de bem-vindo, indicadores de carregamento e notificações mais emocionalmente atraentes.
Sarah Drasner demonstra isso na animação abaixo, usando uma combinação de mudanças de estado de tempo e interatividade.
Veja o Pen Vue-controlled Wall-E de Sarah Drasner (@sdras) no CodePen.