Primers passos amb VueJS 2

Enviat per Jordi Casanovas el Dj, 20/09/2018 - 10:04
vue

Introducció

Si haguéssim de trobar una característica comuna entre tota la gent que ens dediquem al desenvolupament web, segur que estarem d’acord en el fet de que ens agrada estar al dia de les últimes eines i tendències d’aquest món. Molt sovint aquesta inquietud es materialitza en pregunta a reddit, Quora, o similar, amb la forma “Quin framework web em puc posar a aprendre?”. Resposta ràpida: Depèn. La resposta més elaborada es basa en preguntar-se altres qüestions: Quanta gent treballarà en el codi? Quines altres llibreries coneixes? Vols un framework complet amb eines per tot, o vols seleccionar quines microllibreries gestionaran cada funcionalitat? [1]

El dia d’avui podem marcar tres com els frameworks javascript web més coneguts: React, Angular i Vue. Tots tres permeten crear Progressive Web Applications (PWA), que són aplicacions web carregades com qualsevol altra pàgina web, amb l’afegit que ofereixen funcionalitats pròpies d’una aplicació mòbil [2]. Per exemple, són oferides sota HTTPS, poden tenir mode offline, poden oferir notificacions push (notificacions automàtiques), i poden ser afegides a la pantalla inicial del dispositiu [3].

VueJS 2 ha sigut el framework web escollit pel desenvolupament del projecte EVALOE SSD. La característica més important d’aquest framework, és el que defineixen com a progressiu: en comptes de tenir funcionalitats d’aquest que no es faran servir, el framework inclou les funcionalitats bàsiques (com la gestió del DOM, el data binding, o la reactivitat) que es van complementant amb les funcionalitats que interessen (afegir rutes i gestionar els estats, obtenció de dades a través d’una API, o afegir una llibreria d’elements gràfics) [1].

Per acabar d’entendre de què estem parlant, ho mostrarem en un parell d’exemples:

Exemple senzill

Primer, crearem un fitxer html amb un text base tal com el següent:

<!DOCTYPE html>
<html>
<head>
 <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
   <div>
       Primer pas de l'exemple
   </div>
</body>
</html>

En aquest punt, introduirem l’script de vue des del CDN amb l’etiqueta script, i se li afegeix la funció que permet gestionar el DOM a través del framework. Aquesta funció crea una nova instància Vue sobre l’element amb id app. Aleshores, es defineix una variable anomenada header que conté el missatge que volem mostrar, i que ara queda definit per una variable.

<body>
   <div id="app">
       <h1>{{ header }}</h1>
   </div>
   <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
   <script>
       var app = new Vue({
           el: '#app',
           data: {
               header: "Segon pas de l'exemple"
           }
       })
   </script>
</body>

Ara, afegim el següent a sota del header:

<div id="app">
    <h1>{{ header }}</h1>
     <input v-model="header">
</div>

I escrivim al quadre de text que apareix. Canvia el missatge a la vegada? Això és el data binding, que permet canviar el valor de la variable header a través d’elements del DOM. Ara que sabem això, podem endinsar-nos en alguns conceptes més interessants.

Hands On

El primer requeriment per desenvolupar sobre VueJS 2 és tenir el gestor de paquets npm inclòs dins de l’entorn nodejs. Per facilitar tot l’empaquetatge amb l’eina webpack, existeix una interfície de línia de comandes que facilita molt la feina, que s’instal·la amb `npm install -g vue-cli`.

Una vegada instal·lat el vue-cli podem crear el nostre projecte, que usarà webpack, amb la plantilla que ens ofereixen executant `vue init webpack vue-projecte`. Aquesta comanda llança una instal·lació interactiva, on contestarem algunes preguntes sobre alguns components.


? Project name -El nom que volguem-
? Project description -Descripció del projecte-
? Author
? Vue build -STANDALONE-
? Install vue-router? -NO-
? Use ESLint to lint your code? -NO-
? Set up unit tests -NO-
? Setup e2e tests with Nightwatch? -NO-
? Should we run `npm install` for you after the project has been created? -npm install-

S’ha contestat no a moltes opcions que són realment interessants, tot i que per la petita pràctica que fem complicarien la configuració. Però, què són? El vue-router és un component que permet donar gestionar les diferents rutes que pot tenir la nostra aplicació web, definint els paràmetres i les url. El ESLint és una eina que té la funció d’ajudar al desenvolupador a escriure codi d’una manera estructurada i llegible. Per últim, els tests unitaris i els end to end amb Nightwatch ens proporcionen una eina per assegurar la qualitat del codi.

En aquest punt s’ha descarregat un conjunt de fitxers dins la carpeta vue-projecte, dels que passem a explicar els importants:

Vue-projecte

Les carpetes build i config contenen diferents fitxers per gestionar la compilació o el desplegament del codi, i en aquest exemple no les farem servir. La carpeta node_modules conté totes les dependències descrites al nostre package.json, pel que tampoc la tocarem. Per últim, la carpeta static i src/assets contindran els fitxers tals com imatges, amb algunes diferències. L’arxiu index.html inclou l’estructura html amb el div identificat per app, i com a l’exemple anterior, s’inicialitza la instància Vue amb el contingut de l’script src/main.js:

new Vue({
el: '#app',
components: { App },
template: '<App/>'
})

Cal destacar la referència al component App. Els components són que considero com a més important d’aquest framework. Es defineixen com a instàncies reusables de Vue que tenen un nom concret i es componen de tres parts:

  • Template: Codi en HTML on es defineix quina estructura té el component.
  • Script: Codi en Javascript, seguint una estructura concreta, on es defineix quin és el comportament del component.
  • Style: Codi en CSS on es defineix la forma com s’ha de visualitzar el component a partir de regles d’estil.

En aquest cas anterior, està inicialitzant la instància de Vue dins del div identificat per #app, i li està afegint el component App, que el trobarem a App.vue.


Ara que tenim l’estructura bàsica, crearem una aplicació web que consumirà la API pública del conegut joc de cartes Magic The Gathering, mostrant-nos baralles aleatòries de 7 cartes. Primer crearem arxiu anomenat Card.vue, sota la carpeta /src/components, on definirem un component anomenat Card, i que s’encarregarà de mostrar la imatge d’una carta i el seu títol, definits com a props:



<template>
    <div class="card">
        <img v-if=”image !== undefined” class="card" :src="url"/>
  <div v-else>Not available</div>
        <h4> {{ name }} </h4>
    </div> 
</template> 
<script>
 export default {
    name: 'Card',    props: ["name", "url"]
 }
 </script>
 <style>
    .h4 {
        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif
    }
    img.card {
        width: 200px;
    }
    .card {
        display: inline-block;
        margin: 4px;
    }
 </style>

En aquest punt, ja podem introduir tantes cards com es vulgui passant el seu nom i la url on està la seva imatge. Cal destacar el v-if i el v-else, que són condicions les quals mostren la imatge en cas que existeixi, o el text “Not Available” en cas que no es disposi d’imatge.

A continuació, definirem el comportament del component que actua com a base, modificant l’arxiu App.vue:



<template>
  <div id="app">
    <div>
      <button @click="getDeck">new Deck</button>
    </div>
    <card v-for="item in cards" :key="item.id" :name="item.name" :image="item.imageUrl"></card>
  </div>
 </template>
 <script>
 import Card from './components/card'
 export default {
  name: 'App',
  components: {
    Card
  },
  data () {
    return {
      cards: []
    }
  },
  methods: {
    getDeck: function() {  fetch("https://api.magicthegathering.io/v1/cards?pageSize=7&random=true")
      .then((data) => data.json())
      .then(data => this.cards = data.cards)
    }
  }
 }
 </script>

Per entendre millor què fa aquest codi, explicarem primer l’script. Defineix que el component App inclourà el component Card, i que tindrà una variable anomenada cards, una array buida a l’inici. També, es defineix un mètode anomenat getDeck que fa una crida a la API que proporciona la informació de les cartes, fent que la array cards prengui per valor el resultat de la crida. Finalment, al template, es mostra un botó que crida al mètode getDeck, i a sota es mostra el component card, que és interesant donar-li un cop d’ull:

<card v-for="item in cards" :key="item.id" :name="item.name" :image="item.imageUrl"></card>

El v-for indica que es repeteixi aquell component per cadascun dels elements de la array card, passant el valor name i imageUrl de l’element rebut, al name i la image del component card.

Finalment, per arrancar l’entorn local i comprovar el funcionament, cal fer per línia de comandes des del directori arrel del projecte `npm run dev`, al finalitzar el procés us arrancarà el servidor local, retornant per pantalla la URL local que cal visitar (similar a http://localhost:8080). D’altra banda, si el que es vol és muntar el projecte per desplegar-lo a un servidor web, cal fer `npm run build`, que generarà la carpeta /dist amb tots els arxius necessaris per desplegar.

El codi final d’aquest exemple està en aquest repositori de GitHub .

Conclusió

Hem vist que VueJS ofereix el sistema mínim i necessari per desplegar aplicacions web seguint una estructura ordenada i modular. És bastant lleuger, i a mesura que sorgeixen necessitats més potents com autenticació, internacionalització, rutes, etc, s’hi van incorporant els mòduls estrictament necessaris per complir amb aquests requeriments, mantenint neta i fàcil d’entendre l’estructura de l’aplicació web.

Referències

[1] Evan You, The Progressive Framework

[2] Progressive Web Apps, from Wikipedia 

[3] Ciprian Borodescu, 2018 State of Progressive Web Apps

Segueix-nos a

Els nostres articles del bloc d'inLab FIB

         
         

inLab FIB incorpora esCert

Icona ESCERT

First LogoCSIRT Logo

inLab és membre de

CIT UPC