Sintaxe do Modelo de Marcação
A Vue usa uma sintaxe de modelo de marcação baseada na HTML que permite-nos vincular declarativamente o DOM interpretado aos dados da instância do componente subjacente. Todos os modelos de marcação da Vue são HTML sintaticamente válidas que podem ser analisados sintaticamente por navegadores e analisadores sintáticos de HTML compatíveis com a especificação.
Nos bastidores, a Vue compila os modelos de marcação para um código de JavaScript altamente otimizado. Aliada ao sistema de reatividade, a Vue é capaz de descobrir inteligentemente o número mínimo de componentes a reinterpretar e aplicar a quantidade mínima de manipulações do DOM quando o estado da aplicação mudar.
Se estivermos familiarizados com os conceitos do DOM virtual e preferirmos o poder puro da JavaScript, também podemos escrever diretamente funções de interpretação ao invés dos modelos de marcação, com suporte opcional de JSX. No entanto, nota que estas não gozam do mesmo nível de otimizações no momento da compilação como os modelos de marcação.
Interpolação de Texto
A forma mais básica de vinculação de dados é a interpolação de texto usando a sintaxe de "Bigodes" (chaves duplas):
template
<span>Message: {{ msg }}</span>
O marcador do bigode será substituído pelo valor da propriedade msg
da instância do componente correspondente. Este também será atualizado sempre que a propriedade msg
mudar.
HTML Puro
Os bigodes duplos interpretam os dados como texto simples, e não como HTML. No sentido de produzirmos HTML de verdade, precisaremos de usar a diretiva v-html
:
template
<p>Using text interpolation: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
Using text interpolation: <span style="color: red">This should be red.</span>
Using v-html directive: This should be red.
Eis que encontramos algo novo. O atributo v-html
que vemos é chamado de diretiva. As diretivas são prefixadas com v-
para indicar que são atributos especiais fornecidos pela Vue, como podemos ter imaginado, estas aplicam comportamento especial reativo ao DOM interpretado. Eis, que estamos basicamente dizendo para "manter este HTML interno do elemento atualizado com a propriedade rawHtml
sobre a atual instância ativa".
Os conteúdos do span
serão substituídos pelo valor da propriedade rawHtml
, interpretados como HTML simples - os vínculos de dados são ignorados. Nota que não podemos usar v-html
para compor os parciais do modelo de marcação, porque a Vue não é um motor de modelagem de marcação de hipertexto baseado em sequência de caracteres. No lugar disto, os componentes são preferenciais como unidade fundamental para reutilização e composição da interface.
AVISO DE SEGURANÇA
Interpretar dinamicamente HTML arbitrário na nossa aplicação pode ser muito perigoso porque pode facilmente conduzir à vulnerabilidades de XSS. Apenas usamos v-html
em conteúdo de confiança e nunca no conteúdo fornecido pelo utilizador.
Vínculos de Atributo
Os bigodes não podem ser usados dentro dos atributos de HTML. No lugar destes, usamos a diretiva v-bind
:
template
<div v-bind:id="dynamicId"></div>
A diretiva v-bind
instrui a Vue para manter o atributo id
do elemento em sincronia com a propriedade dynamicId
do componente. Se o valor vinculado for null
ou undefined
, então o atributo será removido do elemento interpretado.
Abreviação
Uma vez que a v-bind
é comummente usa, esta tem uma sintaxe abreviada dedicada:
template
<div :id="dynamicId"></div>
Os atributos que começa com os :
podem parecer um pouco diferentes da HTML normal, mas é de fato um carácter válido para nomes de atributo e todos os navegadores suportados pela Vue podem analisá-lo sintaticamente corretamente. Além disto, estes não aparecerem na marcação desenhada final. A sintaxe abreviada é opcional, mas possivelmente a apreciaremos quando aprendermos mais sobre o seu uso mais tarde.
Para o resto do guia, estaremos usando a sintaxe abreviada nos exemplos de código, já que é o uso mais comum para os programadores de Vue.
Atalho de Mesmo Nome
Se o atributo tiver o mesmo nome que o valor de JavaScript sendo vinculado, a sintaxe pode ser muito mais abreviada para omitir o valor do atributo:
template
<!-- o mesmo que `:id="id"` -->
<div :id></div>
<!-- isto também funciona -->
<div v-bind:id></div>
Isto é semelhante a sintaxe de abreviação de propriedade quando declaramos objetos na JavaScript. Nota que esta é uma funcionalidade que está disponível apenas na Vue 3.4+ e superior.
Atributos Booleanos
Os atributos booleanos são atributos que podem indicar valores verdadeiros ou falsos com sua presença sobre um elemento. Por exemplo, disabled
é um dos atributos booleanos mais comummente usados.
A v-bind
funciona de maneira um pouco diferente neste caso:
template
<button :disabled="isButtonDisabled">Button</button>
O atributo disabled
será incluído se isButtonDisabled
tiver um valor verdadeiro. Este também será incluído se o valor for uma sequência de caracteres vazia, mantendo a consistência com <button disabled="">
. Para os outros valores falsos o atributo será omitido.
Vinculando Dinamicamente Vários Atributos
Se tivermos um objeto de JavaScript representando vários atributos que se parece com este:
js
const objectOfAttrs = {
id: 'container',
class: 'wrapper'
}
Nós podemos vinculá-los (os atributos) a um único elemento usando a v-bind
sem um argumento:
template
<div v-bind="objectOfAttrs"></div>
Usando as Expressões da JavaScript
De momento apenas estivemos vinculando às chaves de propriedade simples nos nossos modelos de marcação. Mas a Vue de fato suporta o poder total das expressões de JavaScript dentro de todos os vínculos de dados:
template
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div :id="`list-${id}`"></div>
Estas expressões serão avaliadas como JavaScript no âmbito da aplicação dos dados da instância do componente atual.
Nos modelos de marcação da Vue, as expressões de JavaScript podem ser usadas nas seguintes posições:
- Dentro das interpolações de texto (bigodes)
- No valor do atributo de quaisquer diretivas da Vue (atributos especiais que começam com
v-
)
Somente Expressões
Cada vínculo apenas pode conter uma única expressão. Uma expressão é um pedaço de código que pode ser avaliada para um valor. Uma verificação simples é se pode ser usada depois de return
.
Portanto, as seguintes não funcionarão:
template
<!-- isto é uma declaração, e não uma expressão: -->
{{ var a = 1 }}
<!-- controlo de fluxo também não funcionará, use expressões ternárias -->
{{ if (ok) { return message } }}
Chamando Funções
É possível chamar um método exposto pelo componente dentro duma expressão de vínculo:
template
<time :title="toTitleDate(date)" :datetime="date">
{{ formatDate(date) }}
</time>
NOTA
As funções chamadas dentro das expressões de vínculo serão chamadas todas as vezes que o componente atualizar, então estas não devem possuir quaisquer efeitos colaterais, tais como alterar dados ou acionar operações assíncronas.
Acesso Global Restrito
As expressões do modelo de marcação são isoladas e apenas têm acesso a uma lista restrita de globais. A lista expõe os globais embutidos comummente usados tais como Math
e Date
.
Os globais que não são explicitamente incluídos na lista, por exemplo, propriedades anexadas pelo utilizador sobre window
, não estarão acessíveis nas expressões do modelo de marcação. Nós podemos, no entanto, definir explicitamente os globais adicionais para todas as expressões da Vue adicionado-os à app.config.globalProperties
.
Diretivas
As diretivas são atributos especiais com o prefixo v-
. A Vue fornece um número de diretivas embutidas, incluindo v-html
e v-bind
que introduzimos acima.
Os valores do atributo da diretiva são esperados serem expressões de JavaScript únicas (com a exceção de v-for
, v-on
, e v-slot
, as quais serão discutidas nas suas respetivas seções adiante). O trabalho duma diretiva é aplicar atualizações de maneira reativa ao DOM quando o valor da sua expressão mudar. Consideremos v-if
como um exemplo:
template
<p v-if="seen">Now you see me</p>
Neste exemplo, a diretiva v-if
removeria ou inseriria o elemento <p>
baseada na veracidade do valor da expressão seen
.
Argumentos
Algumas diretivas podem receber um "argumento", denotado por um sinal de dois-pontos depois do nome da diretiva. Por exemplo, a diretiva v-bind
é usada para atualizar um atributo de HTML de maneira reativa:
template
<a v-bind:href="url"> ... </a>
<!-- abreviação -->
<a :href="url"> ... </a>
Neste exemplo, href
é o argumento, o qual diz à diretiva v-bind
para vincular o atributo href
do elemento ao valor da expressão url
. Em resumo, tudo que estiver antes do argumento (isto é, v-bind
) é condensado a um único carácter, :
.
Um outro exemplo é a diretiva v-on
, a qual ouve os eventos do DOM:
template
<a v-on:click="doSomething"> ... </a>
<!-- abreviação -->
<a @click="doSomething"> ... </a>
Neste exemplo, o argumento é o nome do evento a ouvir: click
. A v-on
tem uma abreviação correspondente, nomeadamente o carácter @
. Nós também falaremos sobre a manipulação de evento em mais detalhes.
Argumentos Dinâmicos
Também é possível usar uma expressão de JavaScript num argumento de diretiva envolvendo-a entre colchetes:
template
<!--
Nota que existem algumas restrições à expressão de argumento,
como explicado nas seções "restrições do valor de argumento dinâmico"
e "restrições da sintaxe do argumento dinâmico" abaixo.
-->
<a v-bind:[attributeName]="url"> ... </a>
<!-- abreviação -->
<a :[attributeName]="url"> ... </a>
Neste exemplo, o attributeName
será avaliado dinamicamente como uma expressão de JavaScript, e o seu valor avaliado será usado como valor final para o argumento. Por exemplo, se a instância do nosso componente tiver uma propriedade de dados attributeName
, cujo valor é "href"
, então este vínculo será equivalente à v-bind:href
.
De maneira semelhante, podemos usar os argumentos dinâmicos para vincular um manipulador a um nome de evento dinâmico:
template
<a v-on:[eventName]="doSomething"> ... </a>
<!-- abreviação -->
<a @[eventName]="doSomething">
Neste exemplo, quando o valor do eventName
for "focus"
, v-on:[eventName]
será equivalente à v-on:focus
.
Restrições do Valor do Argumento Dinâmico
Os argumentos dinâmicos são esperados serem avaliados a uma sequência de caracteres, com a exceção de null
. O valor especial null
pode ser usado para remover explicitamente o vínculo. Qualquer outro valor que não for sequência de caracteres acionará um aviso.
Restrições da Sintaxe do Argumento Dinâmico
As expressões de argumento dinâmico têm algumas restrições de sintaxe porque certos caracteres, tais como espaços e aspas, são inválidos dentro dos nomes de atributo de HTML. Por exemplo, o seguinte é inválido:
template
<!-- Isto acionará um aviso de compilação. -->
<a :['foo' + bar]="value"> ... </a>
Se precisarmos de passar um argumento dinâmico complexo, é possivelmente melhor usar uma propriedade computada, a qual cobriremos brevemente.
Quando usamos os modelos de marcação no DOM (modelos de marcação escritos diretamente num ficheiro de HTML), também devemos evitar nomear as chaves com caracteres maiúsculos, já que os navegadores coagirão os nomes de atributo para minúsculas:
template
<a :[someAttr]="value"> ... </a>
O exemplo acima será convertido à :[someattr]
nos modelos de marcação no DOM. Se o nosso componente tiver uma propriedade someAttr
ao invés de someattr
, o nosso código não funcionará. Os modelos de marcação dentro dos componentes de ficheiro único não estão sujeitos a esta restrição.
Modificadores
Os modificadores são sufixos especiais denotados por um ponto, os quais indicam que uma diretiva deve ser vinculada duma maneira especial. Por exemplo, o modificador .prevent
diz a diretiva v-on
para chamar event.preventDefault()
sobre o evento acionado:
template
<form @submit.prevent="onSubmit">...</form>
Depois veremos outros exemplos de modificadores, para a v-on
e para a v-model
, quando explorarmos estas funcionalidades.
E finalmente, eis a sintaxe completa da diretiva visualizada: