Skip to content

3. projeto [vuejs-01]: os fundamentos

Para explicar o código executado em [vuejs-00], vamos simplificá-lo em [vuejs-01]. Duplicamos a pasta [vuejs-00] em [vuejs-01]:

Image

O projeto [vuejs-01] é composto essencialmente por quatro ficheiros:

  • [main.js] e [2] são o ponto de entrada do projeto;
  • [App.vue, HelloWorld.vue] e [3-4] são componentes de [Vue.js], incluindo, de forma opcional, os seguintes elementos:
    • [<template>...</template>]: código HTML;
    • [<script>...</script>]: o código JavaScript associado ao código HTML;
    • [<style>...</style>]: o estilo CSS associado ao código HTML;
  • [public/index.html] [5]: o documento HTML visualizado pelo comando [npm run serve];

O ficheiro [public/index.html] apresentado aquando da execução do projeto é este:


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title>vuejs</title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but vuejs doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- os ficheiros compilados serão inseridos automaticamente -->
  </body>
</html>

Este ficheiro HTML não apresenta, portanto, nada de forma estática. Aqui não existe qualquer código HTML. A exibição é dinâmica: o código jS do projeto irá gerar o HTML, que substituirá na íntegra a baliza [<div id=’app’>] da linha 14. O código HTML, gerado pelo código jS do projeto e inserido no lugar da baliza [<div>] da linha 14, provém das balizas [template] dos componentes [vue.js], cujos ficheiros têm a extensão [.vue].

O código HTML é inserido dinamicamente na linha 14 pelo seguinte script [vuejs-01/main.js]:


// importações
import Vue from 'vue'
import App from './App.vue'

// configuração
Vue.config.productionTip = false

// instanciação do projeto [App]
new Vue({
  render: h => h(App),
}).$mount('#app')

Comentários

  • linha 2: o objeto [Vue] é fornecido pelo framework [vue.js];
  • linha 3: o objeto [App] é fornecido pelo ficheiro [vuejs-01/App.vue];
  • linha 6: configuração do objeto [Vue];
  • linhas 9-11: são as linhas que:
    • geram o código HTML da aplicação. Na linha 10, é o ficheiro [App.vue] que o gera;
    • carregam o código HTML gerado na linha 10 na secção [<div id=’app’></div>] do ficheiro [public/index.html];

Qualquer projeto [Vue.js] pode manter o ficheiro [index.html] tal como está.

O ficheiro [App.vue] do projeto inicial [vuejs-00] é simplificado da seguinte forma no projeto [vuejs-01]:


<template>
  <div id="myApp">
    <img alt="Vue logo" src="./assets/logo.png" />
    <HelloWorld msg="Notre première application Vue.js" />
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";

export default {
  name: "app",
  components: {
    HelloWorld
  }
};
</script>

Comentários

  • Um fragmento [.vue] compreende, no máximo, três secções:
    • [<template>...</template>]: do código HTML;
    • [<script>...</script>]: o código JavaScript associado ao código HTML;
    • [<style>...</style>]: o estilo CSS associado ao código HTML;

Aqui, não temos nenhuma secção [style].

  • linhas 1-6: o código HTML do fragmento (página, componente, vista, ...);
  • linhas 2-5: a secção [template] só pode conter um elemento. Normalmente, insere-se uma secção [div] que engloba todo o HTML do fragmento. Também é possível inserir uma baliza <template>;
  • linha 3: uma imagem;

Image

  • linha 4: um componente denominado [HelloWorld]. O princípio do [Vue.js] consiste em construir páginas web utilizando fragmentos definidos em ficheiros [.vue], como aqui o [App.vue]. Este componente é definido pelo ficheiro [HelloWorld.vue], definido na linha 9 do script jS associado;
  • linha 4: um componente pode aceitar parâmetros. O parâmetro é, neste caso, o atributo [msg];
  • linhas 8-17: o script jS do fragmento (ou componente);
  • linha 9: para poder utilizar o componente [HelloWorld] no componente [App], é necessário importar a sua definição para a parte [script];
  • linhas 11-16: o script define um objeto e exporta-o para o tornar disponível externamente;
  • linha 12: o atributo [name] define o nome do componente exportado;
  • linhas 13-15: o atributo [components] enumera os componentes utilizados pelo componente [App]. Estes são exportados juntamente com ele;

Na linha 9, não é obrigatório que o componente [HelloWorld] tenha o mesmo nome que o ficheiro que o define. Poderia ser importado como [X] e exportado como componente [Bonjour]:

Image

  • linha 14: o componente [X] é exportado com o nome [Bonjour]. É então utilizado com esse nome, na linha 4;

A primeira versão é a mais comum, pelo que definiremos os nossos componentes desta forma;


<template>
  <div id="myApp">
    <img alt="Vue logo" src="./assets/logo.png" />
    <HelloWorld msg="Notre première application Vue.js" />
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";

export default {
  name: "app",
  components: {
    HelloWorld
  }
};
</script>

A linha 14 é um atalho para o código [HelloWorld : HelloWorld]: o componente [HelloWorld] (à direita, importado na linha 9) é exportado com o nome [HelloWorld] (à esquerda).

Image

Simplificamos o componente [HelloWorld.vue] da seguinte forma:


<template>
  <div>
    <h1>{{ msg }}</h1>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    msg: String
  }
};
</script>

Comentários

  • o componente [HelloWorld] tem a mesma estrutura de ficheiro que o componente principal [App];
  • linha 3: aqui temos uma avaliação de uma expressão JavaScript, neste caso a expressão [msg];
  • linhas 10-12: definem as propriedades do componente, mais precisamente os seus parâmetros. Quando o componente [App] instanciou um componente [HelloWorld], fê-lo com a seguinte sintaxe:

<HelloWorld msg="Notre première application Vue.js" />

O componente [HelloWorld] é instanciado atribuindo um valor ao parâmetro (atributo) [msg]. Se seguirmos o [template] do componente [HelloWorld], este passa a ser:


<div>
    <h1>Notre première application Vue.js</h1>
</div>
  • linhas 7-14: as propriedades do componente definidas sob a forma de um objeto que é exportado;
    • linha 9: o componente é exportado com o nome [HelloWorld];
    • linhas 10-12: os seus parâmetros são definidos pela propriedade [props];

Por fim, se reunirmos os modelos dos dois componentes [App, HelloWorld] utilizados, o ficheiro [index.html] apresentado será o seguinte:


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <link rel="icon" href="<%= BASE_URL %>favicon.ico">
  <title>vuejs</title>
</head>
<body>
  <noscript>
    <strong>We're sorry but vuejs doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
  </noscript>
  <div id="myApp">
    <img alt="Vue logo" src="./assets/logo.png" />
    <div>
      <h1>Notre première application Vue.js</h1>
    </div>
  </div></body>
</html>

Executamos a aplicação alterando o comando [serve] [1] do ficheiro [package.json]:

Image

A página apresentada é, então, [2].

Agora, vamos analisar o código desta página:

Image

  • em [1], substituir por [clic droit];
  • em [2], o código-fonte da página. Vemos que este é o código do ficheiro inicial [index.html] e não foi este que foi apresentado. Foi, de facto, a página [index.html] que foi carregada inicialmente. Posteriormente, de forma dinâmica, código JavaScript alterou esta página, mas isso não nos é mostrado;

Quando as páginas são geradas dinamicamente por JavaScript, a opção [2] não serve para nada. É necessário aceder às ferramentas do navegador (F12 no Firefox) para ver o código da página atualmente apresentada:

Image

  • em [1], o inspetor do DOM (Document Object Model) do documento exibido;
  • em [2], o que este DOM contém realmente;
  • [3-4], as ferramentas que utilizaremos para visualizar os objetos JavaScript utilizados pelo framework [Vue.js];
  • [4] é uma extensão (neste caso, para o Firefox) para depurar aplicações [Vue.js]:
    • para o Firefox: [https://addons.mozilla.org/fr/firefox/addon/vue-js-devtools/];
    • para o Chrome: [https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd];

Vamos analisar o separador [Vue] [4]:

Image

A vista [1-4] mostra-nos a estrutura [Vue.js] do documento: a raiz do documento [2] (index.html) inclui o componente [App] (3), que, por sua vez, inclui o componente [HelloWorld] (4). Ao clicar em [4], são apresentadas as propriedades do componente [HelloWorld] [5].

Em [4] (à direita), é possível ver o indicador [$vm0]. Este é o nome da variável que podemos utilizar na consola JavaScript [6] para designar o objeto [HelloWorld]. Vamos fazê-lo:

Image

  • em [2], fazemos com que a expressão [$vm0] seja avaliada, o que tem como efeito exibir a sua estrutura. Normalmente, não teremos de utilizar diretamente esta estrutura;

Terminemos por demonstrar a capacidade de [hot reload] do comando [serve] utilizado para executar o projeto:

  • no [App.vue], altere a mensagem apresentada pelo [HelloWorld]:

Image

  • em [1], altera-se a mensagem apresentada;
  • no [2-3], a página é atualizada automaticamente sem qualquer intervenção da nossa parte;

Vamos agora criar vários projetos [vuejs-xx] para ilustrar os pontos importantes de [Vue.js]. Por «importantes», entenda-se «que iremos utilizar no cliente [vue.js] do servidor de cálculo de impostos». Outros pontos «importantes» serão omitidos caso não sejam utilizados no cliente. Por conseguinte, não será feita uma apresentação exaustiva do [vue.js].