O introducere Vue.js pentru persoanele care cunosc suficient de mult jQuery pentru a se apropia

Sigla pentru Vue.js

Am avut o relație dragoste-ură cu JavaScript de ani de zile.

Am știut limba prin intermediul băiatului preferat al comunității de proiectare și dezvoltare, jQuery. Vedeți, la momentul în care am început să învăț JavaScript, ca un „Designer care codifică”, lucrul cu jQuery a fost o experiență magică. Aș putea face modale fadeIn și fadeOut. Cu o bibliotecă terță parte, aș putea adăuga derulare de paralaxe în portofoliul meu cu un singur apel funcțional. Aproape tot ce aș fi putut visa am fost încapsulat într-un singur fișier de ~ 100kb ...

Și apoi a ieșit Angular. Nu am avut de ales decât să refac întregul meu portofoliu cu cadrul. Și atunci React a ieșit. Nu am avut de ales decât să refac întregul meu portofoliu cu biblioteca. Și atunci a ieșit Vue.js. Nu am avut de ales decât să refac întregul meu portofoliu cu biblioteca ... Vedeți unde merge asta.

Toate glumele deoparte, mi-a plăcut mult să-mi onorez jupurile JavaScript prin construirea lucrurilor de aici și de acolo cu aceste cadre și biblioteci diferite. Am citit nenumărate articole și tutoriale în acest proces, dar niciunul nu s-a lipit de mine mai mult decât piesa lui Shu Uesugi, „React.js Introducere pentru persoanele care știu doar suficient de mult pentru a se apropia”.

Shu ia cititorii - care se presupune că au un anumit nivel de competență cu fundamentele JavaScript și jQuery - într-o călătorie prin lumea React, în timp ce construiesc o clonă a componentei „compun tweet” de pe Twitter.

Acest cadru conceptual mi-a fost destul de util ca cineva care învață cel mai bine făcând. Într-adevăr, de fiecare dată când apare o nouă bibliotecă JavaScript, mă întorc la exemplul din acest articol pentru a testa apele. Așadar, aș dori să împrumut acest cadru în timp ce vă ghid pe toată experiența mea recentă de a învăța Vue.

Înainte de a începe pașii de mai jos, vă încurajez să citiți articolul Shu. El face o treabă fantastică de a vă parcurge codul jQuery pe care l-ați putea scrie pentru a implementa unele dintre aceste funcții. Astfel, și pentru a atenua riscul de concediere, mă voi concentra pe a vă arăta componentele Vue.

Ce construim

Cei mai mulți dintre noi ne tweetează (unii mai prolific decât alții). Deci, probabil, suntem familiarizați cu componenta Interfață de utilizator din imaginea de mai jos.

Caseta „Compune Tweet” de pe Twitter

Credeți sau nu, această componentă UI este un exemplu excelent despre modul în care Vue (și React, conform Shu) vă poate îmbunătăți viața ca dezvoltator JavaScript / jQuery. Elementele acestei componente pe care ne vom concentra pe construirea de astăzi sunt:

  • 3. Am adăugat atributul: dezactivat butonul nostru. Punctul precedent dezactivat indică faptul că am dori să evaluăm conținutul dintre ghilimele ca expresie JavaScript. Dacă am omite colonul, conținutul ar fi tratat ca un șir. Veți remarca, de asemenea, că am adăugat câteva rânduri de CSS pentru a oferi butonului dezactivat un stil vizual distinct.

     Tweet 
    ...
    buton [dezactivat] {
      cursor: nu este permis;
      opacitate: .5;
    }

    4. Am adăugat, de asemenea, o proprietate calculată pe instanța noastră numită tweetIsEmpty. Rețineți că această proprietate este de fapt o funcție care returnează o valoare booleană bazată pe lungimea atributului de tweet al modelului nostru de date. Vue face simplă accesarea modelului dvs. de date atât în ​​HTML (așa cum se arată mai sus), cât și în instanța în sine. Datorită magiei legării datelor în două sensuri, această funcție este evaluată atunci când valoarea tweet-ului este actualizată. Când funcția se evaluează la adevărată, butonul nostru este dezactivat și invers.

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

    Desigur, acest lucru se simțea ca fum și oglinzi când am început pentru prima dată cu Vue. Ceea ce m-a ajutat a fost să văd literalmente ce se întâmplă cu modelul nostru de date sub capotă, în timp ce am interacționat cu componenta. Întrucât putem accesa cu ușurință modelul de date din HTML-ul nostru prin intermediul sintaxiei cretului menționat, putem construi o buclă rapidă de feedback vizual. Scor!

    Valoarea tweet este: {{tweet}}

    Valoarea tweetIsEmpty este: {{tweetIsEmpty}}

    Vă rugăm să nu ezitați să repetați acest pas dacă ceva pe parcurs a fost confuz (fie din cauza abilităților mele slabe de scriere, de codare, fie datorită Vue în sine). Trimiteți un tweet sau lăsați un comentariu dacă aveți întrebări.

    Pasul 3: Implementați a doua caracteristică - Afișați numărul de personaje rămase

    Descrierea caracteristicii: ca tipuri de utilizator, afișați numărul de caractere rămase (din 140) în tweet. Dacă un utilizator a introdus peste 140 de caractere, dezactivați butonul albastru Tweet.

    Până acum am aflat despre proprietățile de legare și calculare a datelor în două sensuri, concepte care sunt chiar miezul Vue. Este ziua noastră norocoasă, deoarece putem folosi aceste concepte pentru a construi următoarea noastră caracteristică: arătând utilizatorilor câte caractere (din 140) rămân și dezactivând butonul dacă această limită este eclipsată.

    Încă o dată, vă voi parcurge atât modificările JavaScript cât și HTML necesare pentru a implementa această caracteristică.

    În JavaScript nostru, am făcut câteva lucruri.

    1. Ca măsură de menaj, am enumerat lungimea maximă a unui tweet (140 de caractere) ca o constantă, MAX_TWEET_LENGTH.
    const MAX_TWEET_LENGTH = 140;

    2. Am adăugat o altă proprietate calculată, caractereRemaining, care returnează dinamic diferența dintre 140 și lungimea tweet-ului introdus de utilizator.

    caractereRemaining: function () {
      returna MAX_TWEET_LENGTH - this.tweet.length;
    }

    3. Am redenumit proprietatea tweetIsEmpty veche la tweetIsOutOfRange și am actualizat logica funcției în consecință. Rețineți cum folosim caracterele calculateRemaining proprietate pentru a obține această valoare. Hooray pentru reutilizarea codului!

    tweetIsOutOfRange: function () {
      returnează acest lucru.charactersRemaining == MAX_TWEET_LENGTH
          || this.charactersReming <0;
     }

    În ceea ce privește aspectul HTML, trebuie să facem doar câteva modificări, datorită puterii legării datelor în două direcții ale Vue.

       {{caractereRemaining}}    Tweet

    Pentru studenții vizuali de acolo, urmăriți magia:

    Pasul 4: Implementarea celei de-a treia caracteristici: Stilarea condiționată a indicatorului „Caractere rămase”

    Descriere caracteristică: la compunerea unui Tweet, culoarea indicatorului „caractere rămase” ar trebui să se schimbe la roșu închis atunci când rămân doar douăzeci de caractere și roșu deschis când rămân zece sau mai puține.

    Manipularea stilului sau clasei unui element poate fi greoaie cu jQuery, iar Vue oferă un mod mult mai curat de a face acest lucru. Abordarea lui Vue se simte mai declarativă, prin faptul că descrii cum vrei să schimbi stilul cevaului (bazat, de exemplu, pe o anumită stare) și îl lași pe Vue să facă ridicarea grea.

    În contextul acestei caracteristici, indicatorul „caractere rămase” are două astfel de stări și o clasă CSS corespunzătoare pentru fiecare.

    1. Când rămân între zece și douăzeci de caractere, indicatorul ar trebui să aibă clasa roșu-închis
    2. Când rămân mai puțin de zece caractere, indicatorul ar trebui să aibă clasa roșu-deschis

    Până acum, creierul tău Vue ar trebui să strige „PROPRIETĂȚI COMPUTATE!” Deci, să obligăm acest creier și să facem legătura cu aceste proprietăți.

    underTwentyMark: function () {
      întoarceți acest lucru.charactersRemaining <= 20
        && this.charactersReming> 10;
      },
    underTenMark: function () {
      returnează acest lucru.charactersRemaining <= 10;
    }

    Cu logica noastră în loc, să aruncăm o privire la unul dintre modurile în care Vue gestionează stilul condiționat: directiva v-bind: class. Această directivă se așteaptă la un obiect ale cărui chei sunt clase CSS și ale căror valori sunt proprietățile calculate corespunzătoare.

    {'dark-red': underTwentyMark, 'light-red': underTenMark}

    Adăugând directiva la eticheta de span care cuprinde indicatorul „caractere rămase”, am completat funcția noastră.

    
      {{ caractere ramase }}
    

    Sub capotă, și datorită legării datelor în două sensuri, Vue se va ocupa de adăugarea și eliminarea acestor clase în funcție de proprietățile calculate specificate.

    Pasul 5: Implementați a patra caracteristică: „Atașați fotografie” UX

    Descriere caracteristică: Permiteți utilizatorilor să atașeze o singură fotografie la tweet-ul lor printr-un dialog de selecție de fișiere. Când fotografia a fost încărcată, arătați-o sub textul și permiteți utilizatorilor să ștergeți fișierul atașat făcând clic pe imagine

    Avertizare corectă: se întâmplă multe în această secțiune. Frumusețea este, în ciuda acestei funcții care adaugă funcționalitate considerabilă, nu va trebui să scriem atât de mult cod. Deci, să începem prin a descompune designul interacțiunii în pași.

    1. Utilizatorul face clic pe butonul „Adaugă fotografie”
    2. Utilizatorul vede un dialog de selectare a fișierelor și poate selecta o fotografie pentru încărcare
    3. La selectarea fotografiei, o casetă apare sub textarea cu fotografia selectată în interior
    4. Utilizatorul face clic pe butonul circular X pentru a elimina fotografia
    5. Utilizatorul vede starea inițială de la pasul 1

    Până în acest moment, nu am efectuat încă nicio gestionare a evenimentelor (ascultarea clicurilor pe butoane, modificările de intrare etc.). După cum vă așteptați, Vue ușurează gestionarea unor astfel de evenimente oferindu-ne directiva v-on (@ pentru scurt). Trecând o metodă ca valoare a acestei directive, putem asculta eficient evenimentele DOM și rula JavaScript atunci când sunt declanșate.

    Înainte de a vă scufunda în funcționalitatea noastră, unele practici cu foc rapid.

    Tratarea evenimentelor este la fel de ușoară precum adăugarea directivei @click la un buton dat și adăugarea unei metode corespunzătoare la cheia de metode din instanța noastră Vue.

    
    ...
    metode: {
      logNameToConsole: function () {
        if (this.name! == 'Donald Trump') {
          console.log (this.name);
        } altfel {
          console.warn („Scuze, nu înțeleg”);
        }
      },
    }

    Înapoi la activitatea noastră de caracteristici ... În acest pas, marcarea și JavaScript-ul nostru s-au schimbat în următoarele moduri:

    1. Am adăugat un buton cu o directivă @click. Când un utilizator face clic pe acest buton, va fi apelată metoda triggerFileUpload.

    Deci, în JavaScript nostru, să adăugăm o cheie de metode pentru instanța noastră Vue cu metoda menționată în interior, precum și un atribut de date pentru fotografia noastră.

    date: {
     foto: nul
    },
    calculat: {},
    metode: {
      triggerFileUpload: function () {
        . Acest $ refs.photoUpload.click (); // LOL CE?
      },
    }

    2. Este notoriu dificil să stilăm intrările de fișiere HTML5. O soluție implică introducerea unei intrări în DOM și ascunderea acesteia cu CSS. Pentru ca browserul să poată deschide selectorul de fișiere native, trebuie să faceți clic pe această intrare. Cu toate acestea, cum se face clic pe el și cum se ocupă clientul de ceea ce încarcă utilizatorul.

    În marcajul nostru, am adăugat o astfel de intrare și am ascuns-o cu o clasă specială de ascundere. Am adăugat, de asemenea, câteva alte atribute demne de apelat:

    • Atributul ref este utilizat pentru a înregistra o referință la un element DOM dat. Având în vedere această referință, cu acesta putem accesa elementul DOM din codul nostru JavaScript. $ Refs.photoUpload. Ceea ce înseamnă că putem declanșa programatic un eveniment de clic () pe acest element, eludând astfel provocarea descrisă mai sus.
    • A face clic pe intrare este un lucru; manipularea fișierului pe care utilizatorul îl încarcă este altul. Din fericire, Vue ne permite să atașăm un operator la evenimentul de schimbare a intrării prin intermediul directivei @change. Metoda prin care trecem la această directivă va fi invocată după ce un utilizator selectează un fișier din selectorul de fișiere. Această metodă, handlePhotoUpload, este destul de simplă
    handlePhotoUpload: function (e) {
      var self = asta;
      var reader = new FileReader ();
          
      reader.onload = funcție (e) {
        // Setați șirul de bază 64 la cheia „fotografie” a modelului de date
        self.photo = (e.target.result);
      }
      // Citiți fișierul de încărcare ca șir de bază 64
      reader.readAsDataURL (e.target.files [0]);
     }

    Respirați adânc, pentru că aproape am terminat cu această caracteristică!

    După ce un utilizator a încărcat o fotografie, trebuie să afișăm o casetă sub textarea cu fotografia selectată în interior. La fel cum stilul condiționat al elementelor este o adiere la Vue, la fel este și redarea condiționată sau afișarea elementelor. Veți observa că în HTML-ul nostru, am adăugat următorul marcaj sub textarea.

      
               ...             

    Vue oferă o mână de asistenți de șabloane (v-if, v-show, v-else, etc) pentru a vă ajuta să afișați și să ascundeți conținutul condiționat. Când expresia JavaScript transmisă acestei directive se evaluează ca fiind adevărat, elementul este redat și invers.

    În cazul nostru, am adăugat o instrucțiune v-if care evaluează proprietatea calculată photoHasBeenUploaded.

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

    Atunci când această funcție se evaluează la adevărat - când cheia foto a modelului nostru de date nu este egală cu nul - întreaga div este redată. Voilà!

    Iar în interiorul acestei divizii redăm două elemente:

    1. Imaginea atașată, trecând conținutul cheii foto a modelului nostru de date la directiva Vue v-bind: src
    2. Un buton de ștergere care prezintă un alt exemplu de handler @ clic, acesta invocând o funcție care „înlătură” fotografia prin setarea cheii foto a modelului nostru de date pe null.
    removePhoto: function () {
      this.photo = null;
    }

    Aproape am ajuns.

    Pasul 6: Corecția, utilizatorul poate atașa „fotografii”

    Deci, putem gestiona eficient un utilizator care atașează o fotografie la Tweet, dar dacă ar dori să încarce multe fotografii?

    Până acum, ar trebui să vă gândiți la ceva: „Bănuiesc că singura schimbare semnificativă aici este aceea de a putea afișa mai multe imagini în acea casetă care apare condiționată sub textarea, având în vedere că deja am conectat gestionarii de evenimente ...” Și ai dreptate! Să aruncăm o privire la pașii pe care trebuie să îi urmăm

    1. Trebuie să ne actualizăm modelul de date prin schimbarea unei fotografii în fotografii, noua cheie fiind un tablou de șiruri base64 (nu un singur șir de bază 64)
    date: {
      fotografii: []
    },

    2. Trebuie să ne actualizăm proprietatea calculată de fotografieHasBeenUploaded pentru a verifica lungimea noii noastre chei de fotografii, care este acum un tablou.

    photoHasBeenUploaded: function () {
      returna aceasta.photos.length> 0;
    }

    3. Trebuie să ne actualizăm manipulatorul de intrare @change pentru a ne bucla de fișierele încărcate și a le împinge pe cheia fotografiilor noastre.

    handlePhotoUpload: function (e) {
      var self = asta;
      var files = e.target.files;
      for (let i = 0; i 
        reader.onloadend = funcție (evt) {
          self.photos.push (evt.target.result);
        }
        reader.readAsDataURL (fișiere [i]);
      }
    },

    Pe partea HTML, însă, trebuie să ne îndreptăm către un teritoriu nou. Iterarea asupra datelor și redarea conținutului cu jQuery pot fi greoaie.

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

    Din fericire, Vue oferă o abstractizare asupra acestei proceduri prin intermediul directivei v-for. Această directivă se așteaptă să furnizați o expresie sub formă de (chestie, index) în collectionOfThings, în care collectionOfThings este tabloul sursă, lucru este un alias pentru elementul matrice care este iterat, iar indexul este, bine, indexul elementului respectiv .

    Un exemplu prototipic poate arăta astfel:

    În cazul în care înainte aveam un element de figură singular pentru fotografia încărcată de utilizator, vom avea acum N taguri de cifre corespunzătoare lungimii sursei de fotografii.

    Din fericire pentru noi, marcajul nostru nu trebuie să se schimbe prea drastic, deoarece structura generală a designului este în continuare aceeași.

    
      
        ...
      
      
    

    O singură modificare pe care trebuie să o facem se învârte în jurul metodei removePhoto care, înainte, a stabilit cheia foto singulară pe modelul nostru de date la nul. Acum, din moment ce avem un număr de N de fotografii, trebuie să trecem indexul elementului la metoda removePhoto și să scoatem elementul din tablou.

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

    Pasul 7: animație + credit suplimentar

    În UI Twitter, componenta „Compose Tweet” se deschide într-o modalitate. Pentru marea noastră finală, aș dori să aplic toate tehnicile Vue pe care le-am învățat până acum și să introduc încă una: tranziții.

    Ciclu de viață de tranziție

    Un cuvânt de precauție, tranzițiile sunt un subiect vast în ținuturile Vue. Urmează să examinăm și să punem în aplicare o felie subțire a acestei funcționalități, și anume integrarea unei biblioteci de animație a unei terțe părți, Velocity JS, cu Vue.

    Pe scurt, Vue oferă o componentă de tranziție care vă permite să adăugați animații de introducere / ieșire pentru elementul conținut în interior, cu condiția ca elementul să fie setat să fie afișat condiționat prin, de exemplu, o directivă v-if sau v-show.

    
        
               

    În exemplul nostru, am atașat două metode care corespund cu două evenimente din ciclul de viață al tranziției: v-on: enter și v-on: leave. Astfel, am adăugat aceste definiții ale metodei instanței noastre Vue, amânându-ne de Velocity JS pentru a ne estompa modalitățile de intrare și de ieșire.

    metode: {
      modalEnter: function (el, done) {
        Viteză (el, 'fadeIn', {durata: 300, complet: terminat, afișare: 'flex'})
      },
      modalLeave: function (el, done) {
        Viteză (el, 'fadeOut', {durata: 300, complet: făcut})
      }
    }

    După cum am menționat mai sus, tranziția se va declanșa atunci când elementul conținut în interior este setat condiționat să fie afișat. Deci, la divizarea interioară a componentei noastre de tranziție, am adăugat o declarație v-dacă a cărei valoare este o modalitate booleană. Să actualizăm modelul de date al instanței noastre în consecință.

    date: {
      modalShowing: false
    }

    Acum, când vrem să arătăm modalul, tot ce trebuie să facem este să-l stabilim pe boolean pe adevărat!

    Și scrie o metodă care să se potrivească.

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

    Cu unele trucuri CSS, am atașat și un fundal de evenimente de clic pe fundal, astfel încât utilizatorii să poată ascunde modalitatea. Scor!

    Concluzie

    Ei bine, sper că nu a fost prea dureros (și că ai învățat un lucru sau două pe parcurs). Am aruncat o privire doar asupra unei mici aspecte a ceea ce Vue are de oferit, deși, după cum am menționat mai sus, aceste concepte sunt cruciale pentru deblocarea potențialului Vue.

    Recunosc, este nedrept să comparăm Vue cu jQuery. Sunt produse din diferite perioade, cu cazuri de utilizare destul de diferite. Cu toate acestea, pentru cei care s-au luptat în modul lor de a învăța manipularea DOM și gestionarea evenimentelor prin jQuery, sper că aceste concepte sunt o respirație de aer curat pe care o puteți aplica pe fluxul de lucru.