Un'introduzione di Vue.js per le persone che conoscono abbastanza jQuery per cavarsela

Il logo per Vue.js

Ho avuto una relazione di odio-amore con JavaScript per anni.

Ho avuto modo di conoscere il linguaggio tramite il ragazzo da montare preferito della comunità di progettazione e sviluppo, jQuery. Vedete, quando ho iniziato a studiare JavaScript, come "Designer che codifica", lavorare con jQuery è stata un'esperienza magica. Potrei far dissolvere i modali e dissolvenza. Con una libreria di terze parti, ho potuto aggiungere lo scorrimento di parallasse al mio portafoglio con una sola chiamata di funzione. Quasi tutto ciò che avrei potuto sognare era incapsulato in un singolo file ~ 100kb ...

E poi è uscito Angular. Non avevo altra scelta che rifare il mio intero portafoglio con il framework. E poi React è uscito. Non avevo altra scelta che rifare il mio intero portafoglio con la biblioteca. E poi è uscito Vue.js. Non avevo altra scelta che rifare il mio intero portafoglio con la biblioteca ... Vedi dove sta andando.

A parte tutti gli scherzi, mi è piaciuto molto affinare le mie braciole JavaScript attraverso la costruzione di cose qua e là con questi diversi framework e librerie. Ho letto innumerevoli articoli ed esercitazioni nel processo, ma nessuno mi ha attaccato più del pezzo di Shu Uesugi, "Introduzione a React.js per le persone che sanno abbastanza jQuery da cavarsela".

Shu porta i lettori - che si presume abbiano un certo livello di competenza con i fondamenti di JavaScript e jQuery - in un viaggio attraverso il mondo di React mentre costruiscono un clone del componente "compose tweet" di Twitter.

Questa cornice concettuale mi è stata molto utile come qualcuno che impara meglio facendo. In effetti, ogni volta che esce una nuova libreria JavaScript, mi ritrovo a tornare all'esempio di questo articolo per testare le acque. E quindi, vorrei prendere in prestito questo frame mentre passo tutti attraverso la mia recente esperienza di apprendimento di Vue.

Prima di iniziare i passaggi seguenti, ti incoraggio vivamente a leggere l'articolo di Shu. Fa un ottimo lavoro guidandoti attraverso il codice jQuery che potresti scrivere per implementare alcune di queste funzionalità. Pertanto, e al fine di mitigare il rischio di ridondanza, mi concentrerò sul mostrarti i dettagli di Vue.

Cosa stiamo costruendo

Molti di noi twittano (alcuni in modo più prolifico di altri). Quindi probabilmente abbiamo familiarità con il componente dell'interfaccia utente nello screenshot seguente.

La casella

Che ci crediate o no, questo componente dell'interfaccia utente è un ottimo esempio di come Vue (e React, secondo Shu) potrebbero migliorare la vostra vita come sviluppatore JavaScript / jQuery. Gli elementi di questo componente che ci concentreremo sulla costruzione oggi sono:

  • La

    3. Abbiamo aggiunto l'attributo: disabled al nostro pulsante. I due punti che precedono disabilitato indicano che vorremmo valutare il contenuto tra virgolette come espressione JavaScript. Se dovessimo omettere i due punti, il contenuto verrebbe trattato come una stringa. Noterai anche che abbiamo aggiunto alcune righe di CSS per dare al pulsante disabilitato uno stile visivo distinto.

     Tweet 
    ...
    pulsante [disabilitato] {
      cursore: non consentito;
      opacità: 0,5;
    }

    4. Abbiamo anche aggiunto una proprietà calcolata sulla nostra istanza chiamata tweetIsEmpty. Tieni presente che questa proprietà è in realtà una funzione che restituisce un valore booleano in base alla lunghezza dell'attributo tweet del nostro modello di dati. Vue semplifica l'accesso al tuo modello di dati sia in HTML (come mostrato sopra) che nell'istanza stessa. Grazie alla magia dell'associazione dati bidirezionale, questa funzione viene valutata quando viene aggiornato il valore del tweet. Quando la funzione restituisce true, il nostro pulsante è disabilitato e viceversa.

    tweetIsEmpty: function () {
      return this.tweet.length === 0;
    }

    Devo ammettere che quando ho iniziato con Vue mi è sembrato fumo e specchi. Ciò che mi ha aiutato è stato vedere letteralmente cosa stava succedendo al nostro modello di dati, mentre interagivo con il componente. Poiché possiamo facilmente accedere al nostro modello di dati nel nostro HTML tramite la summenzionata sintassi parentesi graffa, possiamo creare un ciclo di feedback rapido e visivo. Punto!

    Il valore di tweet è: {{tweet}}

    Il valore di tweetIsEmpty è: {{tweetIsEmpty}}

    Sentiti libero di ripetere questo passaggio se qualcosa lungo la strada era confuso (o a causa delle mie scarse capacità di scrittura o di programmazione o a causa di Vue stesso). Invia un tweet o lascia un commento se hai domande particolari.

    Passaggio 3: implementare la seconda funzione - Mostra il numero di caratteri rimanenti

    Descrizione delle caratteristiche: Mentre un utente digita, mostra il numero di caratteri rimanenti (su 140) nel tweet. Se un utente ha inserito più di 140 caratteri, disabilitare il pulsante blu Tweet.

    Finora abbiamo appreso sull'associazione di dati bidirezionale e le proprietà calcolate, concetti che sono alla base di Vue. È il nostro giorno fortunato, perché possiamo sfruttare questi concetti per costruire la nostra prossima funzione: mostrare agli utenti quanti caratteri (su 140) rimangono e disabilitare il pulsante se questo limite viene eclissato.

    Ancora una volta, ti guiderò attraverso le modifiche JavaScript e HTML necessarie per implementare questa funzione.

    Nel nostro JavaScript, abbiamo fatto alcune cose.

    1. Come misura di pulizia, abbiamo elencato la lunghezza massima di un tweet (140 caratteri) come costante, MAX_TWEET_LENGTH.
    const MAX_TWEET_LENGTH = 140;

    2. Abbiamo aggiunto un'altra proprietà calcolata, charactersRemaining, che restituisce dinamicamente la differenza tra 140 e la lunghezza del tweet inserito dall'utente.

    charactersRemaining: function () {
      return MAX_TWEET_LENGTH - this.tweet.length;
    }

    3. Abbiamo rinominato la vecchia proprietà tweetIsEmpty in tweetIsOutOfRange e aggiornato di conseguenza la logica della funzione. Nota come stiamo usando la proprietà charactersRemaining calcolata per derivare questo valore. Evviva il riutilizzo del codice!

    tweetIsOutOfRange: function () {
      return this.charactersRemaining == MAX_TWEET_LENGTH
          || this.charactersRemaining <0;
     }

    Per quanto riguarda l'HTML, dobbiamo solo apportare alcune modifiche, grazie alla potenza dell'associazione dati bidirezionale di Vue.

       {{charactersRemaining}}    Tweet

    Per gli studenti visivi là fuori, guarda la magia:

    Passaggio 4: implementare la terza funzione: stile condizionale dell'indicatore "Caratteri rimanenti"

    Descrizione della funzione: quando si compone un Tweet, il colore dell'indicatore “caratteri rimanenti” dovrebbe diventare rosso scuro quando rimangono solo venti caratteri e rosso chiaro quando ne rimangono dieci o meno.

    Manipolare lo stile o la classe di un elemento può essere ingombrante con jQuery e Vue offre un modo molto più pulito di farlo. L'approccio di Vue sembra più dichiarativo, in quanto descrivi come vuoi che lo stile di qualcosa cambi (basato, ad esempio, su un dato stato) e lasci che Vue faccia il lavoro pesante.

    Nel contesto di questa funzione, il nostro indicatore "caratteri rimanenti" ha due di questi stati e una corrispondente classe CSS per ciascuno.

    1. Quando rimangono tra dieci e venti caratteri, l'indicatore dovrebbe avere la classe rosso scuro
    2. Quando rimangono meno di dieci caratteri, l'indicatore dovrebbe avere la classe rosso-chiaro

    Ormai il tuo cervello Vue dovrebbe gridare "PROPRIETÀ COMPUTATE!" Quindi, obbligiamo questo cervello e colleghiamo quelle proprietà.

    underTwentyMark: function () {
      restituisce this.charactersRemaining <= 20
        && this.charactersRemaining> 10;
      },
    underTenMark: function () {
      restituisce this.charactersRemaining <= 10;
    }

    Con la nostra logica in atto, diamo un'occhiata a uno dei modi in cui Vue gestisce lo stile condizionale: la direttiva v-bind: class. Questa direttiva prevede un oggetto le cui chiavi sono classi CSS e i cui valori sono le proprietà calcolate corrispondenti.

    {"rosso scuro": underTwentyMark, "rosso chiaro": underTenMark}

    Aggiungendo la direttiva al tag span che racchiude il nostro indicatore "caratteri rimanenti", abbiamo completato la nostra funzione.

    
      {{ caratteri rimanenti }}
    

    Sotto il cofano, e grazie all'associazione dati bidirezionale, Vue gestirà l'aggiunta e la rimozione di queste classi in funzione delle proprietà calcolate specificate.

    Passaggio 5: implementare la quarta funzione: UX "Allega foto"

    Descrizione della funzione: Consenti agli utenti di allegare una singola foto al loro tweet tramite una finestra di dialogo di selezione file. Quando la foto è stata caricata, mostrala sotto l'area di testo e consenti agli utenti di eliminare l'allegato facendo clic sull'immagine

    Avviso equo: in questa sezione si stanno verificando molte cose. Il bello è che, nonostante questa funzionalità aggiunga una notevole funzionalità, non dovremo scrivere molto codice. Quindi, cominciamo suddividendo il design dell'interazione in passaggi.

    1. L'utente fa clic sul pulsante "Aggiungi foto"
    2. L'utente visualizza una finestra di dialogo di selezione file e può selezionare una foto da caricare
    3. Dopo aver selezionato la foto, viene visualizzata una casella sotto l'area di testo con la foto selezionata all'interno
    4. L'utente fa clic sul pulsante X circolare per rimuovere la foto
    5. L'utente vede lo stato iniziale dal passaggio 1

    Fino a questo punto, non abbiamo ancora gestito gli eventi (ascolto dei clic sui pulsanti, immissione delle modifiche, ecc.). Come ci si potrebbe aspettare, Vue semplifica la gestione di tali eventi offrendo la direttiva v-on (@ in breve). Passando un metodo come valore di questa direttiva, possiamo effettivamente ascoltare gli eventi DOM ed eseguire JavaScript quando vengono attivati.

    Prima di immergerci nel nostro lavoro, alcune pratiche di tiro rapido.

    La gestione degli eventi è semplice come aggiungere la direttiva @click a un determinato pulsante e aggiungere un metodo corrispondente alla chiave method sulla nostra istanza di Vue.

    
    ...
    metodi: {
      logNameToConsole: function () {
        if (this.name! == 'Donald Trump') {
          console.log (this.name);
        } altro {
          console.warn ('Siamo spiacenti, non capisco');
        }
      },
    }

    Torna al nostro lavoro sulle funzionalità ... In questo passaggio, il nostro markup e JavaScript sono cambiati nei seguenti modi:

    1. Abbiamo aggiunto un pulsante con una direttiva @click. Quando un utente fa clic su questo pulsante, verrà chiamato il metodo triggerFileUpload.

    Quindi, nel nostro JavaScript, aggiungiamo una chiave di metodi alla nostra istanza di Vue con detto metodo all'interno, nonché un attributo di dati per la nostra foto.

    dati: {
     foto: null
    },
    calcolato: {},
    metodi: {
      triggerFileUpload: function () {
        . Questo $ refs.photoUpload.click (); // LOLWUT?
      },
    }

    2. È notoriamente difficile modellare gli input di file HTML5. Una soluzione alternativa consiste nell'inserire un input nel DOM e nasconderlo con CSS. Affinché il browser possa aprire il selettore di file nativo, è necessario fare clic su questo input. Il modo in cui viene cliccato e come il client gestisce ciò che l'utente carica, tuttavia, è una questione diversa.

    Nel nostro markup, abbiamo aggiunto uno di questi input e nascosto con una speciale classe hide. Abbiamo anche aggiunto alcuni altri attributi che vale la pena chiamare:

    • L'attributo ref viene utilizzato per registrare un riferimento a un determinato elemento DOM. Dato questo riferimento, possiamo accedere all'elemento DOM nel nostro codice JavaScript con questo. $ Refs.photoUpload. Ciò significa che possiamo attivare a livello di programmazione un evento click () su questo elemento, aggirando così la sfida sopra descritta.
    • Fare clic sull'input è una cosa; la gestione del file che l'utente carica è un altro. Fortunatamente, Vue ci consente di associare un gestore all'evento change dell'input tramite la direttiva @change. Il metodo che passiamo a questa direttiva verrà invocato dopo che un utente seleziona un file dal selettore file. Questo metodo, handlePhotoUpload, è abbastanza semplice
    handlePhotoUpload: function (e) {
      var self = this;
      var reader = new FileReader ();
          
      reader.onload = function (e) {
        // Imposta quella stringa 64 di base sulla chiave "foto" del nostro modello di dati
        self.photo = (e.target.result);
      }
      // Leggi il file di upload come stringa 64 base
      reader.readAsDataURL (e.target.files [0]);
     }

    Fai un respiro profondo, perché abbiamo quasi finito con questa funzione!

    Una volta che un utente ha caricato una foto, dobbiamo mostrare una casella sotto l'area di testo con la foto selezionata all'interno. Proprio come lo stile condizionale degli elementi è un gioco da ragazzi con Vue, così anche il rendering condizionale o la visualizzazione degli elementi. Noterai che nel nostro HTML abbiamo aggiunto il seguente markup sotto l'area di testo.

      
        

    Vue offre una manciata di helper di template (v-if, v-show, v-else, ecc.) Per aiutarti a mostrare e nascondere i contenuti in modo condizionale. Quando l'espressione JavaScript passata a questa direttiva viene valutata come vera, l'elemento viene visualizzato e viceversa.

    Nel nostro caso, abbiamo aggiunto un'istruzione v-if che valuta la proprietà calcolata photoHasBeenUploaded.

    photoHasBeenUploaded: function () {
      restituire this.photo! == null;
    }

    Quando quella funzione viene valutata vera - quando la chiave fotografica del nostro modello di dati non è uguale a null - viene visualizzato l'intero div. Ecco!

    E all'interno di quel div rendiamo due elementi:

    1. L'immagine che è stata allegata, passando il contenuto della chiave fotografica del nostro modello di dati alla direttiva v-bind: src di Vue
    2. Un pulsante Elimina che presenta un altro esempio del gestore @ click, questo particolare che richiama una funzione che "rimuove" la foto impostando la chiave della foto del nostro modello di dati su null.
    removePhoto: function () {
      this.photo = null;
    }

    Siamo quasi li.

    Passaggio 6: correzione, l'utente può allegare "foto"

    Quindi, possiamo gestire efficacemente un utente che allega una foto al Tweet, e se volesse caricare molte foto?

    Ormai, dovresti pensare a qualcosa con l'effetto di: "Immagino che l'unico cambiamento significativo qui sia la possibilità di mostrare più immagini in quella casella che appare condizionatamente sotto l'area di testo, considerando che abbiamo già collegato i nostri gestori di eventi ..." hai ragione! Diamo un'occhiata ai passaggi che dobbiamo seguire

    1. Dobbiamo aggiornare il nostro modello di dati cambiando foto in foto, la nuova chiave è una matrice di stringhe base64 (non una singola stringa base64)
    dati: {
      fotografie: []
    },

    2. Dobbiamo aggiornare la nostra proprietà calcolata photoHasBeenUploaded per verificare la lunghezza della nostra nuova chiave foto, che ora è un array.

    photoHasBeenUploaded: function () {
      restituisce this.photos.length> 0;
    }

    3. Dobbiamo aggiornare il nostro gestore di input @change per passare in rassegna i file caricati e inserirli nella chiave delle foto.

    handlePhotoUpload: function (e) {
      var self = this;
      file var = e.target.files;
      for (let i = 0; i 
        reader.onloadend = function (evt) {
          self.photos.push (evt.target.result);
        }
        reader.readAsDataURL (file [i]);
      }
    },

    Sul lato HTML, tuttavia, dobbiamo imbarcarci in un nuovo territorio. Iterare sui dati e renderizzare i contenuti con jQuery può essere complicato.

    var array = [1, 2, 3, 4, 5];
    var newHTML = [];
    per (var i = 0; i ' + array [i] + '');
    }
    $ ( "Elemento ") html (newHTML.join ("")).;

    Per fortuna, Vue offre un'astrazione su questa procedura tramite la direttiva v-for. Questa direttiva si aspetta che tu fornisca un'espressione sotto forma di (cosa, indice) in collectionOfThings, dove collectionOfThings è l'array di origine, cosa è un alias per l'elemento dell'array su cui viene ripetuto, e l'indice è, beh, l'indice di quell'elemento .

    Un esempio prototipico potrebbe apparire così:

    Dove prima avevamo un singolo elemento di figura per la foto caricata dall'utente, ora avremmo N tag di figura corrispondenti alla lunghezza della matrice di origine delle foto.

    Fortunatamente per noi, il nostro markup non deve cambiare troppo drasticamente poiché la struttura complessiva del design è sempre la stessa.

      

    L'unica modifica che dobbiamo apportare ruota attorno al metodo removePhoto che, prima, impostava la chiave della foto singola sul nostro modello di dati su null. Ora, dato che abbiamo N numero di foto, dobbiamo passare l'indice dell'elemento al metodo removePhoto ed estrarre quell'elemento dall'array.

    removePhoto: function (index) {
      this.photos.splice (indice, 1);
    }

    Passaggio 7: animazione + credito extra

    Nell'interfaccia utente di Twitter, il componente "Compose Tweet" si apre in modalità modale. Per il nostro gran finale, vorrei applicare tutte le tecniche Vue che abbiamo imparato finora e introdurne un'altra: le transizioni.

    Ciclo di vita di transizione

    Un avvertimento, le transizioni sono un argomento vasto nella terra dei Vue. Esamineremo e implementeremo una sottile porzione di questa funzionalità, ovvero l'integrazione di una libreria di animazione di terze parti, Velocity JS, con Vue.

    In breve, Vue fornisce un componente di transizione che consente di aggiungere animazioni di invio / uscita per l'elemento contenuto all'interno, a condizione che l'elemento sia impostato per essere visualizzato in modo condizionale tramite, ad esempio, una direttiva v-if o v-show.

    
        
               

    Nel nostro esempio, abbiamo collegato due metodi che corrispondono a due eventi nel ciclo di vita della transizione: v-on: enter e v-on: leave. Abbiamo quindi aggiunto queste definizioni di metodo alla nostra istanza Vue, rimandando a Velocity JS per far sbiadire il nostro modal in e out.

    metodi: {
      modalEnter: function (el, done) {
        Velocity (el, 'fadeIn', {durata: 300, completo: fatto, display: 'flex'})
      },
      modalLeave: function (el, done) {
        Velocity (el, 'fadeOut', {durata: 300, completo: fatto})
      }
    }

    Come accennato in precedenza, la transizione si attiverà quando l'elemento contenuto all'interno è impostato condizionalmente per essere visualizzato. Quindi, sul div interno del nostro componente di transizione, abbiamo aggiunto una dichiarazione v-if il cui valore è un modal booleano Showing. Cerchiamo di aggiornare di conseguenza il modello di dati della nostra istanza.

    dati: {
      modalShowing: false
    }

    Ora, quando vogliamo mostrare il modale, tutto ciò che dobbiamo fare è impostare quel booleano su vero!

    E scrivi un metodo da abbinare.

    hideModal: function () {
      this.modalShowing = false;
    },
    showModal: function () {
      this.modalShowing = true;
    },

    Con alcuni trucchi CSS, abbiamo anche collegato un gestore di eventi click allo sfondo, in modo che gli utenti possano nascondere il modale. Punto!

    Conclusione

    Beh, spero che non sia stato troppo doloroso (e che tu abbia imparato una cosa o due lungo la strada). Abbiamo dato solo uno sguardo a ciò che Vue ha da offrire, anche se, come detto sopra, questi concetti sono cruciali per sbloccare il potenziale di Vue.

    Lo ammetto, non è giusto confrontare Vue con jQuery. Sono prodotti di epoche diverse, con casi d'uso piuttosto diversi. Tuttavia, per coloro che hanno faticato ad imparare la manipolazione del DOM e la gestione degli eventi attraverso jQuery, spero che questi concetti siano una boccata d'aria fresca che puoi applicare al tuo flusso di lavoro.