Sviluppo fullstack con AdonisJS parte 2: Configurazione di VueJS

Sviluppo fullstack con AdonisJS parte 2: Configurazione di VueJS

Come attivare il framework frontend VueJS in un progetto AdonisJS

Foto di Pavel Nekoranec su Unsplash

Premessa

Questo articolo fa parte di una serie che illustra come costruire un’applicazione con AdonisJS e VueJS. Se ti fossi perso la prima parte inizia da qui.

Installare VueJS v3

Procediamo a installare VueJS alla versione 3. Seguendo le istruzioni di Adonis su come configurare Vue 3 apriamo innanzitutto il file webpack.config.js che troviamo nella root di progetto. Cerchiamo nel file la parte commentata intitolata “Enable Vue loader” e sostituiamo il codice commentato con il seguente:

// webpack.config.js
Encore.enableVueLoader(() => {}, {
  version: 3,
  runtimeCompilerBuild: true,
  useJsx: false,
})

Eseguiamo ora da terminale il seguente comando (fermare il server con ctrl+c se è ancora avviato):

npm i vue@next vue-loader@next @vue/compiler-sfc

Webpack Encore ha configurato come file di partenza resources/js/app.js che è incluso nella prima pagina rappresentata dal file welcome.edge con l’istruzione @entryPointScripts('app')

Se riavviate il server e provate ad aggiungere nel file app.js l’istruzione console.log("Hello") troverete questo messaggio nella console javascript del browser.

In questo file quindi aggiungiamo le istruzioni base per attivare VueJS nella nostra welcome page:

// app.js
import { createApp } from 'vue'
import App from './components/App'

const app = createApp(App)
const vm = app.mount('#app')

Il codice non fa altro che creare un’app VueJS che verrà montata in un elemento con id “app” (ultima riga) e che mostrerà di default un componente App che dobbiamo ancora creare.

Creiamo quindi una cartella components in resources/js e al suo interno il file App.vue che conterrà il seguente codice:

<!-- App.vue -->
<script>
export default {
  name: 'App',
}
</script>

<template>
  <h1>Welcome to My Manager</h1>
</template>

Questo file descrive un componente Vue ed è composto da due parti: nel tag “script” abbiamo le istruzioni javascript e quindi la business logic del componente; nel tag template abbiamo la parte HTML e quindi gli elementi che vanno a comporre la grafica.

Nota: in genere il tag <template> viene proposto per primo ma personalmente preferisco anticipare il tag <script> perché normalmente contiene le informazioni più importanti sul componente.

Ci rimane solo da creare nella welcome page un elemento con id “app” che permetta a Vue di montare la nostra app. Modifichiamo quindi il file welcome.edge in modo che contenga nel tag body questo codice:

<!-- welcome.edge -->
<!-- ... -->
<body>
  <main>
    <div id="app">
    </div>
  </main>
</body>
<!-- ... -->

Ora, se abbiamo salvato tutti i file, visitando di nuovo la welcome page dovremmo vedere il nostro nuovo titolo “Welcome to My Manager” caricato dinamicamente dall’app Vue.

Possiamo vedere all’opera le prime caratteristiche di interattività in Vue modificando il file App.vue come segue:

<!-- App.vue -->
<script>
export default {
  name: 'App',
  data() {
    return {
      count: 0,
    }
  },
  methods: {
    increaseCount() {
      this.count++
    },
  },
}
</script>

<template>
  <h1>Welcome to My Manager</h1>
  <div>Count {{ count }}</div>
  <button @click="increaseCount()">increase</button>
</template>

Abbiamo aggiunto uno stato con la proprietà data che definisce il valore count che useremo come contatore. La proprietà methods permette di definire più funzioni da eseguire all’interno del componente: il metodo increaseCount va ad incrementare di uno il valore di count ogni volta che è richiamato.

Nel template infine abbiamo stampato il valore corrente di count usando le doppie parentesi graffe e abbiamo collegato il metodo increaseCount all’evento click di un bottone: ogni volta che premerete il bottone vedrete il contatore aumentare di una cifra in tempo reale.

Per concludere il tour base di VueJS aggiungiamo anche un po’ di stile utilizzando il tag “style”:

<!-- App.vue -->
<script>
export default {
  name: 'App',
  data() {
    return {
      count: 0,
    }
  },
  methods: {
    increaseCount() {
      this.count++
    },
  },
}
</script>

<template>
  <h1 class="mb-md">Welcome to My Manager</h1>
  <div class="mb-md">Count {{ count }}</div>
  <button @click="increaseCount()">increase</button>
</template>

<style scoped>
.mb-md {
  margin-bottom: 1rem;
}

button {
  border: none;
  background: #5a45ff;
  color: #fff;
  padding: 0.8rem 1.6rem;
  text-transform: uppercase;
  border-radius: 4px;
}
</style>

Configurare il router di VueJS

Nelle moderne Single Page Application (SPA) un elemento fondamentale è il Router ovvero una libreria che prenda il controllo della navigazione utente tra le pagine tramite javascript; rispetto al classico metodo di navigazione che carica un’intera pagina HTML comprese le parti condivise (intestazione, barra laterale, ecc…), questa strategia velocizza molto i tempi di caricamento e permette di avere il pieno controllo delle logiche di navigazione.

La libreria Vue Router svolge questo compito egregiamente, vediamo come installarla.

Innanzi tutto installiamo il package della libreria:

npm install vue-router@4

Attiviamo Vue Router nella nostra app Vue modificando il file app.js :

// app.js
import { createApp } from 'vue'
import { createRouter, createWebHashHistory } from 'vue-router'
import App from './components/App'
import routes from './routes'

import '../css/app.css'

const router = createRouter({
  history: createWebHashHistory(),
  routes,
})

const app = createApp(App)

app.use(router)

const vm = app.mount('#app')

Breve spiegazione: abbiamo importato dalla libreria “vue-router” due funzioni: la prima per creare l’istanza di un router e la seconda per definire il sistema di storicizzazione che nel nostro caso sarà “web hash”. Attiviamo il router attraverso il metodo “use”.

Il codice a questo punto darà un errore perché non esiste ancora il file routes.js importato alla quarta riga. Andiamo a creare il file nella stessa cartella di app.js e inseriamo questo contenuto:

// routes.js
import Home from './pages/Home'
import About from './pages/About'

const routes = [
  { name: 'home', path: '/', component: Home },
  { name: 'about', path: '/about', component: About },
]

export default routes

Questo file definisce gli indirizzi di navigazione dell’app: ad ogni indirizzo faremo montare un componente vue dedicato che chiameremo genericamente “pagina”.

Creiamo quindi le prime due pagine in una cartella dedicata pages chiamandole rispettivamente Home.vue e About.vue:

<!-- Home.vue -->
<script>
export default {
  name: 'Home',
}
</script>

<template>
  <h1>Home</h1>
</template>

<!-- About.vue -->
<script>
export default {
  name: 'About',
}
</script>

<template>
  <h1>About</h1>
</template>

Ora il codice non dovrebbe più dare errori perché tutti i file richiesti sono esistenti ma non è ancora possibile apprezzare le potenzialità del router perché manca un punto di innesto in cui includere le pagine definite in navigazione. Andiamo quindi ad aggiornare il file App.vue eliminando le vecchie prove del contatore ed inserendo la navigazione:

<!-- App.vue -->
<script>
export default {
  name: 'App',
}
</script>

<template>
  <hr />
  <router-link to="/">Home</router-link> | <router-link to="/about">About</router-link>
  <hr />
  <router-view></router-view>
</template>

Abbiamo aggiunto due componenti resi disponibili da “vue-router”: router-view monta il contenuto della navigazione in base all’attuale URL; router-link crea un collegamento per navigare ad una specifica “route” e quindi, nel nostro caso, ad una pagina.

Nella pagina principale troverete quindi due nuovi link; premendo sul link “About” vedrete apparire la pagina “About.vue” appena sotto al menù. Il link infatti porta all’indirizzo ”/#/about” che viene interpretato dal router il quale, trovando corrispondenza con la proprietà “path” della route “about”, monterà il relativo componente “About.vue”.

Grazie a questo tipo di composizione dei componenti i link alle pagine sono stati dichiarati una sola volta nel template principale lasciando le pagine interne “Home” e “About” libere da ripetizioni e ridondanze.

Ripartire da qui

Abbiamo configurato un buon punto di partenza per generare dei nuovi progetti con AdonisJS e VueJS. Se può esservi utile potrete scaricare il risultato finale da questo repository: https://github.com/marco-mazzocchi/adonis-vue-boilerplate

Il prossimo passo

Nel prossimo articolo vedremo come installare una libreria che fornisca dei componenti per disegnare facilmente la nostra User Interface (UI).

Commenti