En Vue.js-introduktion til folk, der kender lige nok jQuery til at komme forbi

Logoet til Vue.js

Jeg har haft et kærligheds-had-forhold til JavaScript i årevis.

Jeg fik kendskab til sproget ved hjælp af design- og udviklingssamfundets yndlingspiskende dreng, jQuery. På det tidspunkt, hvor jeg begyndte at lære JavaScript, som en "Designer der koder", var det en magisk oplevelse at arbejde med jQuery. Jeg kunne gøre modaler til at fadeIn og fadeOut. Med et tredjepartsbibliotek kunne jeg tilføje parallax-rulning til min portefølje med kun et enkelt funktionskald. Næsten alt, hvad jeg muligvis havde drømt om, blev indkapslet i en enkelt, ~ 100kb fil ...

Og så kom Angular ud. Jeg havde ikke andet valg end at gøre om hele min portefølje med rammerne. Og så kom React ud. Jeg havde ikke andet valg end at gøre om hele min portefølje med biblioteket. Og så kom Vue.js ud. Jeg havde intet andet valg end at gøre om hele min portefølje med biblioteket ... Du kan se, hvor dette går hen.

Alle vittigheder til side, jeg har haft stor glæde af at slå mine JavaScript-chops gennem bygning af ting her og der med disse forskellige rammer og biblioteker. Jeg har læst utallige artikler og tutorials i processen, men ingen har holdt sig sammen med mig mere end Shu Uesugis stykke, "React.js Introduktion til folk, der kender bare nok jQuery at komme forbi."

Shu tager læsere - som antages at have et vist niveau af færdigheder med JavaScript-grundlæggende elementer og jQuery - med på en rejse gennem React-verdenen, når de bygger en klon af Twitter's “compose tweet” -komponent.

Denne konceptuelle ramme var ganske nyttig for mig som nogen, der lærer bedst ved at gøre. Faktisk, hver gang et nyt JavaScript-bibliotek kommer ud, finder jeg mig selv tilbage til eksemplet fra denne artikel for at teste farvandet. Og så vil jeg gerne låne denne ramme, når jeg leder jer alle gennem min nylige oplevelse af at lære Vue.

Før du begynder på trinnene nedenfor, opfordrer jeg dig meget til at læse Shus artikel. Han gør et fantastisk stykke arbejde med at lede dig gennem den jQuery-kode, du muligvis skriver, for at implementere nogle af disse funktioner. Således for at mindske risikoen for afskedigelse vil jeg fokusere på at vise dig ind-og-ud af Vue.

Hvad vi bygger

De fleste af os tweet (nogle mere prolifisk end andre). Så vi er sandsynligvis bekendt med brugergrænsefladekomponenten i skærmbilledet nedenfor.

Twitter's boks

Tro det eller ej, denne UI-komponent er et godt eksempel på, hvordan Vue (og React, pr. Shu) kan forbedre dit liv som JavaScript / jQuery-udvikler. Elementerne i denne komponent, som vi vil fokusere på at bygge i dag, er:

  • 3. Vi tilføjede attributtet: deaktiveret til vores knap. Tykktarmen forud for deaktiveret angiver, at vi gerne vil evaluere indholdet i citaterne som et JavaScript-udtryk. Hvis vi skulle udelade tyktarmen, ville indholdet blive behandlet som en streng. Du skal også bemærke, at vi har tilføjet et par linjer CSS for at give den deaktiverede knap en tydelig visuel styling.

     Tweet 
    ...
    knap [deaktiveret] {
      markør: ikke tilladt;
      opacitet: .5;
    }

    4. Vi tilføjede også en beregnet egenskab på vores eksempel kaldet tweetIsEmpty. Bemærk, at denne egenskab faktisk er en funktion, der returnerer en boolesk værdi baseret på længden af ​​vores datamodells tweet-attribut. Vue gør det dødt enkelt at få adgang til din datamodel både i HTML (som vist ovenfor) og i selve forekomsten. Takket være magien ved tovejsindbinding evalueres denne funktion, når værdien af ​​tweet opdateres. Når funktionen evalueres til sand, er vores knap deaktiveret, og vice versa.

    tweetIsEmpty: funktion () {
      returner this.tweet.length === 0;
    }

    Det føltes ganske vist som røg og spejle, da jeg først kom i gang med Vue. Hvad hjalp mig var bogstaveligt talt at se, hvad der skete med vores datamodel under hætten, da jeg interagerede med komponenten. Da vi let kan få adgang til vores datamodel i vores HTML via den førnævnte krøllede brace-syntaks, kan vi opbygge en hurtig, visuel feedback-loop. Score!

    Værdien af ​​ tweet er: {{tweet}}

    Værdien af ​​ tweetIsEmpty er: {{tweetIsEmpty}}

    Du er velkommen til at gentage dette trin, hvis noget undervejs var forvirrende (enten på grund af mine dårlige skrive- eller kodningsevner, eller på grund af selve Vue). Send en tweet eller skriv en kommentar, hvis du har nogle spørgsmål.

    Trin 3: Implementere den anden funktion - Vis antallet af resterende tegn

    Funktionsbeskrivelse: Som en bruger skriver du antallet af resterende tegn (ud af 140) i tweeten. Hvis en bruger har indtastet mere end 140 tegn, skal du deaktivere den blå Tweet-knap.

    Indtil videre har vi lært om tovejsbinding og beregne egenskaber, koncepter, der er kernen i Vue. Det er vores heldige dag, fordi vi kan udnytte disse koncepter til at opbygge vores næste funktion: at vise brugerne, hvor mange tegn (ud af 140) der er tilbage, og deaktivere knappen, hvis denne grænse er formørket.

    Endnu en gang vil jeg lede dig gennem både JavaScript- og HTML-ændringerne, der kræves for at implementere denne funktion.

    I vores JavaScript har vi gjort et par ting.

    1. Som husholdningsforanstaltning opregner vi den maksimale længde af en tweet (140 tegn) som en konstant, MAX_TWEET_LENGTH.
    const MAX_TWEET_LENGTH = 140;

    2. Vi tilføjede en anden beregnet egenskab, charactersRemaining, som dynamisk returnerer forskellen mellem 140 og længden af ​​den brugerindtastede tweet.

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

    3. Vi omdøbte den gamle tweetIsEmpty-egenskab til tweetIsOutOfRange og opdaterede funktionens logik i overensstemmelse hermed. Bemærk, hvordan vi bruger de beregnede tegnRemaining-egenskab til at udlede denne værdi. Hurra for genbrug af kode!

    tweetIsOutOfRange: funktion () {
      returner this.charactersRemaining == MAX_TWEET_LENGTH
          || this.charactersRemaining <0;
     }

    På HTML-siden af ​​tingene er vi kun nødt til at foretage et par ændringer takket være kraften i Vues tovejsbinding.

       {{charactersRemaining}}    Tweet

    For de visuelle elever derude, se magien:

    Trin 4: Implementere den tredje funktion: Betinget styling af indikatoren "Resterende tegn"

    Funktionsbeskrivelse: Når du komponerer en Tweet, skal farven på indikatoren "resterende tegn" ændres til mørkerødt, når der kun er tyve tegn tilbage, og lys rød, når der er ti eller færre tilbage.

    Manipulering af et elements stil eller klasse kan være besværligt med jQuery, og Vue tilbyder en meget renere måde at gøre det på. Vues tilgang føles mere erklærende, idet du beskriver, hvordan du ønsker, at noget skal ændres (baseret på f.eks. En given tilstand), og du lader Vue udføre den tunge løft.

    I forbindelse med denne funktion har vores "tegn tilbage" indikator to sådanne tilstande og en tilsvarende CSS-klasse for hver.

    1. Når der er mellem ti og tyve tegn tilbage, skal indikatoren have den mørkerøde klasse
    2. Når der er mindre end ti tegn tilbage, skal indikatoren have den lyserøde klasse

    I øjeblikket skal din Vue-hjerne råbe "COMPUTED PROPERTIES!" Så lad os forpligte denne hjerne og slå disse egenskaber op.

    underTwentyMark: funktion () {
      return this.charactersRemaining <= 20
        && this.charactersRemaining> 10;
      },
    underTenMark: funktion () {
      returner dette. CharactersRemaining <= 10;
    }

    Med vores logik på plads, lad os se på en af ​​måderne, hvorpå Vue håndterer betinget styling: v-bind: klassedirektivet. Dette direktiv forventer et objekt, hvis nøgler er CSS-klasser, og hvis værdier er de tilsvarende beregne egenskaber.

    {'mørkerød': underTwentyMark, 'lysrød': underTenMark}

    Ved at tilføje direktivet til det span-tag, der omslutter vores “tegn tilbage”, har vi afsluttet vores funktion.

    
      {{charactersRemaining}}
    

    Under hætten, og takket være to-vejs databinding, vil Vue håndtere tilføjelse og fjernelse af disse klasser som en funktion af de specificerede beregne egenskaber.

    Trin 5: Implementere den fjerde funktion: “Vedhæft foto” UX

    Funktionsbeskrivelse: Tillad brugere at vedhæfte et enkelt foto til deres tweet via en filvalgdialog. Når billedet er blevet uploadet, skal du vise det under tekstområdet og give brugerne mulighed for at slette vedhæftningen ved at klikke på billedet

    Fair advarsel: der er meget, der sker i dette afsnit. Skønheden er, at selv om denne funktion tilføjer betydelig funktionalitet, behøver vi ikke at skrive så meget kode. Så lad os starte med at opdele interaktionsdesignet i trin.

    1. Bruger klikker på knappen "Tilføj foto"
    2. Brugeren ser en filvælgerdialog og kan vælge et foto, der skal uploades
    3. Ved valg af foto vises en boks under tekstområdet med det valgte foto indeni
    4. Brugeren klikker på den cirkulære X-knap for at fjerne billedet
    5. Brugeren ser initialtilstand fra trin 1

    Indtil nu har vi endnu ikke udført nogen begivenhedshåndtering (lytter til knapklik, inputændringer osv.). Som du kunne forvente, gør Vue det nemt at håndtere sådanne begivenheder ved at give os v-on-direktivet (@ kort). Ved at videregive en metode som en værdi af dette direktiv, kan vi effektivt lytte til DOM-begivenheder og køre JavaScript, når de udløses.

    Før du dykker ned i vores funktionsarbejde, skal du praktisere hurtig brand.

    Begivenhedshåndtering er lige så let som at tilføje @click-direktivet til en given knap og tilføje en tilsvarende metode til metodenøglen i vores Vue-forekomst.

     Log brugernavn 
    ...
    metoder: {
      logNameToConsole: funktion () {
        if (this.name! == 'Donald Trump') {
          console.log (this.name);
        } andet {
          console.warn ('Beklager, jeg forstår ikke');
        }
      },
    }

    Tilbage til vores funktionsarbejde ... I dette trin er vores markup og JavaScript ændret på følgende måder:

    1. Vi tilføjede en knap med et @click-direktiv. Når en bruger klikker på denne knap, kaldes triggerFileUpload-metoden.
     ... 

    Så lad os i vores JavaScript tilføje en metodenøgle til vores Vue-forekomst med den nævnte metode inden i, samt en dataattribut til vores foto.

    data: {
     foto: null
    },
    beregnet: {},
    metoder: {
      triggerFileUpload: funktion () {
        . Denne $ refs.photoUpload.click (); // LOLWUT?
      },
    }

    2. Det er notorisk vanskeligt at style HTML5-filindgange. Én løsning involverer at indsætte et input i DOM og skjule det med CSS. For at browseren skal åbne den oprindelige filvælger, skal dette input klikkes. Hvordan det bliver klikket, og hvordan klienten håndterer, hvad brugeren uploader, er dog en anden sag.

    I vores markering har vi tilføjet et sådant input og skjult det med en speciel skjulklasse. Vi har også tilføjet et par andre attributter, der er værd at kalde:

    • Ref-attributten bruges til at registrere en henvisning til et givet DOM-element. Med denne henvisning kan vi få adgang til DOM-elementet i vores JavaScript-kode med dette. $ Refs.photoUpload. Hvilket betyder, at vi kan programmere udløse en klik () begivenhed på dette element og derved omgå udfordringen beskrevet ovenfor.
    • Klik på input er en ting; håndtering af filen, som brugeren uploader, er en anden. Heldigvis tillader Vue os at knytte en behandler til inputens ændringshændelse via @change-direktivet. Metoden, som vi videregiver til dette direktiv, aktiveres, når en bruger vælger en fil fra filvælgeren. Denne metode, handlePhotoUpload, er ret ligetil
    handlePhotoUpload: funktion (e) {
      var selv = dette;
      var reader = new FileReader ();
          
      reader.onload = funktion (e) {
        // Sæt den base 64 streng til vores datamodell 'foto' nøgle
        self.photo = (e.target.result);
      }
      // Læs uploadfil som base 64-streng
      reader.readAsDataURL (e.target.files [0]);
     }

    Tag en dyb indånding, for vi er næsten færdige med denne funktion!

    Når en bruger har uploadet et foto, er vi nødt til at vise en boks under tekstområdet med det valgte foto indeni. Ligesom den betingede styling af elementer er en leg med Vue, så er også den betingede gengivelse eller visning af elementer. Bemærk, at vi i vores HTML har tilføjet følgende markup under tekstområdet.

                  ...             

    Vue tilbyder en håndfuld skabelonhjælpere (v-if, v-show, v-else osv.) Til at hjælpe dig med at vise og skjule indhold betinget. Når JavaScript-udtrykket, der sendes til dette direktiv, evalueres til sandt, gengives elementet og omvendt.

    I vores tilfælde tilføjede vi en v-if-erklæring, der evaluerer den beregnede egenskabsfotoHasBeenUploaded.

    photoHasBeenUploaded: funktion () {
      returner dette. Foto! == null;
    }

    Når denne funktion evalueres til sand - når fototasten i vores datamodel ikke er lig med null - bliver hele div gengivet. Sådan!

    Og inden for denne div giver vi to elementer:

    1. Billedet, der blev vedhæftet, ved at videregive indholdet af vores datamodels fotonøgle til Vues v-bind: src-direktiv
    2. En sleteknap, der indeholder et andet eksempel på @-klikhåndtereren, netop denne, der påkalder en funktion, der "fjerner" billedet ved at indstille vores datamodellens fototast til null.
    removePhoto: funktion () {
      this.photo = null;
    }

    Vi er næsten der.

    Trin 6: Korrektion, bruger kan vedhæfte "fotos"

    Så vi kan effektivt håndtere en bruger, der knytter et foto til Tweet, men hvad hvis hun gerne vil uploade mange fotos?

    I øjeblikket skulle du tænke noget med virkningen af: "Jeg gætter på, at den eneste betydningsfulde ændring her er at kunne vise flere billeder i den boks, der vises betinget under tekstområdet, i betragtning af at vi allerede har tilsluttet vores begivenhedshåndterere ..." Og du har ret! Lad os se på de trin, vi skal følge

    1. Vi er nødt til at opdatere vores datamodel ved at ændre foto til fotos, hvor den nye nøgle er en række base64-strenge (ikke en enkelt base64-streng)
    data: {
      fotos: []
    },

    2. Vi er nødt til at opdatere vores computereegenskabsfotoHasBeenUploaded for at kontrollere længden af ​​vores nye fotosnøgle, som nu er en matrix.

    photoHasBeenUploaded: funktion () {
      returner dette. Fotos.length> 0;
    }

    3. Vi er nødt til at opdatere vores input @change handler for at sløjfe over de uploadede filer og skubbe dem på vores fotos nøgle.

    handlePhotoUpload: funktion (e) {
      var selv = dette;
      var filer = e.target.files;
      for (lad i = 0; i 
        reader.onloadend = funktion (evt) {
          self.photos.push (evt.target.result);
        }
        reader.readAsDataURL (filer [i]);
      }
    },

    På HTML-siden skal vi dog gå ind på nyt territorium. Iterering over data og gengivelse af indhold med jQuery kan være besværligt.

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

    Heldigvis tilbyder Vue en abstraktion af denne procedure ved hjælp af v-for-direktivet. Dette direktiv forventer, at du giver et udtryk i form af (ting, indeks) i collectionOfThings, hvor collectionOfThings er kildearrayet, ting er et alias for det arrayelement, der itereres på, og indeks er, vel, indekset for det element .

    Et prototypisk eksempel kan se sådan ud:

    Hvor før vi havde et ental figurelement til det bruger-uploadede foto, vil vi nu have N-figur tags, der svarer til længden på fotoskildearrayet.

    Heldig for os behøver vores markering ikke at ændre sig for drastisk, da den overordnede struktur af designet stadig er den samme.

    
      
        ...
      
      
    

    Den ene ændring, som vi er nødt til at foretage, drejer sig om removePhoto-metoden, som før satte den entale fototast på vores datamodel til null. Da vi har N antal fotos, skal vi overføre elementets indeks til removePhoto-metoden og trække elementet ud af matrixen.

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

    Trin 7: Animation + Ekstra kredit

    I Twitter's UI åbnes komponenten "Compose Tweet" i en modal. Til vores store finale vil jeg gerne anvende alle de Vue-teknikker, vi har lært indtil videre, og introducere en mere: overgange.

    Overgangs livscyklus

    Et forsigtighedsord, overgange er et stort emne i Vue-land. Vi vil undersøge og implementere en tynd skive af denne funktionalitet, nemlig at integrere et 3. parts animationsbibliotek, Velocity JS, med Vue.

    I en nøddeskal giver Vue en overgangskomponent, der giver dig mulighed for at tilføje enter / forlad animationer til det element indeholdt inden forudsat at elementet er indstillet til at vises betinget via for eksempel et v-if eller v-show-direktiv.

    
        
               

    I vores eksempel har vi vedhæftet to metoder, der svarer til to begivenheder i overgangslivet: v-on: enter og v-on: leave. Vi har således tilføjet disse metodedefinitioner til vores Vue-forekomst og udskudt til Velocity JS for at falme vores modal ind og ud.

    metoder: {
      modalEnter: funktion (el, udført) {
        Hastighed (el, 'fadeIn', {varighed: 300, komplet: udført, display: 'flex'})
      },
      modalLeave: funktion (el, udført) {
        Hastighed (el, 'fadeOut', {varighed: 300, komplet: udført})
      }
    }

    Som nævnt ovenfor vil overgangen udløse, når det indeholdte element er betinget af indstillet til visning. Så på den indre del af vores overgangskomponent har vi tilføjet en v-if-erklæring, hvis værdi er en boolsk modalShowing. Lad os opdatere vores forekomsts datamodel i overensstemmelse hermed.

    data: {
      modalShowing: falsk
    }

    Når vi nu ønsker at vise modalen, er alt, hvad vi skal gøre, at indstille den boolske til sand!

     Skriv Tweet 

    Og skriv en metode til at matche.

    hideModal: funktion () {
      this.modalShowing = falsk;
    },
    showModal: funktion () {
      this.modalShowing = sandt;
    },

    Med nogle CSS-trickery har vi også knyttet en klikhændelseshåndterer til baggrunden, så brugere kan skjule modalen. Score!

    Konklusion

    Nå, jeg håber, det ikke var for smertefuldt (og at du lærte en ting eller to undervejs). Vi kiggede kun på en lille spalte af, hvad Vue har at tilbyde, skønt disse koncepter, som nævnt ovenfor, er afgørende for at frigøre Vue's potentiale.

    Jeg indrømmer, det er uretfærdigt at sammenligne Vue med jQuery. Det er produkter fra forskellige tidspunkter med ganske forskellige anvendelsessager. For dem, der har kæmpet sig for at lære DOM-manipulation og begivenhedshåndtering gennem jQuery, håber jeg, at disse koncepter er et frisk pust, som du kan anvende til din arbejdsgang.