Vínculos de Classe e Estilo
Um necessidade comum de vínculo de dados é a manipulação da lista de classe e estilos em linha dum elemento. Uma vez que class
e style
são ambos atributos, podemos usar a v-bind
para atribuí-las um valor de sequência de caracteres dinamicamente, da mesma maneira que podemos fazer com os outros atributos. No entanto, tentar gerar estes valores usando a concatenação de sequência de caracteres pode ser aborrecido e propenso a erros. Por esta razão, a Vue fornece otimizações especiais quando v-bind
é usada com class
e style
. Além das sequências de caracteres, as expressões também podem avaliar-se para objetos e vetores.
Vinculando Classes de HTML
Vinculando aos Objetos
Nós podemos passar um objeto à :class
(abreviação para v-bind:class
) para alternar classes dinamicamente:
template
<div :class="{ active: isActive }"></div>
A sintaxe acima significa que a presença da classe active
será determinada pela veracidade da propriedade de dados isActive
.
Nós podemos ter várias classes alternadas tendo mais campos no objeto. Além disto, a diretiva :class
também pode coexistir com um atributo class
simples. Então dado o seguinte estado:
js
const isActive = ref(true)
const hasError = ref(false)
E o seguinte modelo de marcação:
template
<div
class="static"
:class="{ active: isActive, 'text-danger': hasError }"
></div>
Esta interpretará:
template
<div class="static active"></div>
Quando isActive
ou hasError
mudar, a lista de classe será atualizada de acordo. Por exemplo, se hasError
tornar-se true
, a lista de classe tornar-se-á "static active text-danger"
.
O objeto vinculado não precisa de estar em linha:
js
const classObject = reactive({
active: true,
'text-danger': false
})
template
<div :class="classObject"></div>
Isto produzirá:
template
<div class="active"></div>
Nós também podemos vincular à uma propriedade computada que retorna um objeto. Isto é um padrão comum e poderoso:
js
const isActive = ref(true)
const error = ref(null)
const classObject = computed(() => ({
active: isActive.value && !error.value,
'text-danger': error.value && error.value.type === 'fatal'
}))
template
<div :class="classObject"></div>
Vinculando aos Vetores
Nós podemos vincular :class
à um vetor para aplicar uma lista de classes:
js
const activeClass = ref('active')
const errorClass = ref('text-danger')
template
<div :class="[activeClass, errorClass]"></div>
O que interpretará:
template
<div class="active text-danger"></div>
Se também gostaríamos de alternar condicionalmente uma classe na lista, podemos fazer isto com uma expressão ternária:
template
<div :class="[isActive ? activeClass : '', errorClass]"></div>
Isto sempre aplicará errorClass
, mas activeClass
só será aplicada quando isActive
for verdadeira.
No entanto, isto pode ser um pouco verboso se tivermos várias classes condicionais. É por isto que também é possível usar a sintaxe de objeto dentro da sintaxe de vetor:
template
<div :class="[{ active: isActive }, errorClass]"></div>
Com os Componentes
Esta seção pressupõe o conhecimento de Componentes. Não hesite em saltá-la e voltar mais tarde.
Quando usamos o atributo class
sobre um componente com um único elemento de raiz, estas classes serão adicionadas ao elemento de raiz do componente, e combinados com qualquer classe já existente neste.
Por exemplo, se tivermos um componente nomeado MyComponent
com o seguinte modelo de marcação:
template
<!-- modelo de marcação do componente filho -->
<p class="foo bar">Hi!</p>
Então adicionamos algumas classes quando o usamos:
template
<!-- quando usamos o componente -->
<MyComponent class="baz boo" />
O HTML interpretado será:
template
<p class="foo bar baz boo">Hi</p>
O mesmo é verdadeiro para os vínculos de classe:
template
<MyComponent :class="{ active: isActive }" />
Quando isActive
for verdadeiro, o HTML interpretado será:
template
<p class="foo bar active">Hi</p>
Se o nosso componente tiver vários elementos de raiz, precisaríamos de definir qual elemento receberá esta classe. Nós podemos fazer isto usando a propriedade de componente $attrs
:
template
<!-- modelo de marcação de MyComponent usando $attrs -->
<p :class="$attrs.class">Hi!</p>
<span>This is a child component</span>
template
<MyComponent class="baz" />
Interpretará:
html
<p class="baz">Hi!</p>
<span>This is a child component</span>
Nós podemos aprender mais sobre a herança de atributo do componente na seção Atributos de Herança.
Vinculando Estilos Em Linha
Vinculando aos Objetos
O :style
suporta a vinculação à valores de objeto de JavaScript - este corresponde à uma propriedade style
do elemento de HTML:
js
const activeColor = ref('red')
const fontSize = ref(30)
template
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
Embora as chaves de "caixaDeCamelo" sejam recomendadas, :style
também suporta as chaves de propriedades de CSS em "caixa-espetada" (que corresponde à como são usadas na CSS real) - por exemplo:
template
<div :style="{ 'font-size': fontSize + 'px' }"></div>
Muitas vezes é uma boa ideia vincular diretamente à um objeto de estilo para o modelo de marcação estar mais limpo:
js
const styleObject = reactive({
color: 'red',
fontSize: '13px'
})
template
<div :style="styleObject"></div>
Novamente, o vínculo de estilo de objeto é muitas vezes usado em conjunto com as propriedades computadas que retornam objetos.
Vinculando aos Vetores
Nós podemos vincular o :style
à um vetor de vários objetos de estilo. Estes objetos serão combinados e aplicados ao mesmo elemento:
template
<div :style="[baseStyles, overridingStyles]"></div>
Prefixação Automática
Quando usarmos uma propriedade de CSS que requer um prefixo fornecedor no :style
, a Vue adicionará automaticamente o prefixo apropriado. A Vue faz isto verificando durante a execução quais propriedades de estilo são suportadas no navegador atual. Se o navegador não suportar uma propriedade em especial então várias variantes prefixadas serão testadas para tentar encontrar uma que seja suportada.
Vários Valores
Nós podemos fornecer um vetor de vários valores (prefixados) à uma propriedade de estilo, por exemplo:
template
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
Isto apenas interpretará o último valor do vetor que o navegador suporta. Neste exemplo, interpretará display: flex
para os navegadores que suportam a versão sem prefixo de caixa flexível, ou melhor dizendo flexbox
.