Nõuanded ja nipid korduvkasutatavate kasutajaliidese komponentide loomiseks

Foto autor Farzard Nazifi

Selles artiklis tahan jagada mõningaid näpunäiteid ja näpunäiteid, mida kasutan Ember.js abil meie põhilise esikülje raamatukogu ehitamisel. Kuna tal pole sellega varem kontakti olnud, on see olnud suurepärane õppimisvõimalus. Loodan, et kutid naudivad seda! Pange tähele, et artiklis esitatud ideede näitlikustamiseks kasutatav kood sisaldab lihtsalt piisavalt teavet, et asjast aru saada. Selles kasutatakse ka mõnda Ember.js terminoloogiat, kuid mõisted on mõeldud raamistangnostikaks.

Eesmärgid

Lihtsustatult öeldes on raamatukogu ehitamise nõuded järgmised:

  1. See peab olema produktiivne.
  2. See peab olema hooldatav.
  3. See peab olema järjekindel.

Lähenemisviisid

Vähendage äriloogikat

Üks sagedamini esinevaid probleeme projektide puhul on komponendid, mis sisaldavad neis liiga palju loogikat. Seega selliste ülesannete täitmine, mis teoreetiliselt jäävad oma ulatusest välja.

Enne funktsionaalsuse rakendamist on hea välja tuua mõned ülesanded, mille eest komponent vastutab.

Kujutage ette, et me ehitame nupukomponenti.

Ma tahaksin, et saaksin:

  • Teatage, mis tüüpi nupp see on - esmane või tavaline
  • Nupu sees kuvatava sisu (ikooni ja teksti) teavitamine
  • Nupu keelamine või lubamine
  • Tehke klõpsamisel mõni toiming

Kuna sellel on väike ülevaade, tõmmake selle komponendi ehitamise protsessi erinevad osad laiali. Proovige kindlaks teha, kuhu asju võiks paigutada.

1 - tüüp ja sisu on komponendipõhised, nii et neid saab komponendifaili paigutada.

Kuna tüüp on - teatud määral - vajalik, lisageme kinnituse juhul, kui väärtust ei antud.

const type = get (see, 'tüüp');
const tüüpi = {
  esmane: 'btn - esmane',
  tavaline: 'btn - tavaline',
}
tagasi (tüüp)? tüübid [tüüp]: tüübid.regulaarne;

Mulle meeldib omaduste kaardistamine objektiks, kuna see võimaldab asju ilma suurema vaevata skaleerida - juhuks, kui vajame ohunuppu või midagi taolist.

2 - puudega olekut võib leida erinevatest komponentidest, näiteks sisendist. Korduste vältimiseks saab selle käitumise viia moodulisse või mõnda muusse jagatud struktuuri - inimesed nimetavad seda miksiniks.

3 - klõpsamistoimingut võib leida erinevatest komponentidest. Nii et seda saab teisaldada ka teise faili ja see ei tohiks sisaldada loogikat - helistage lihtsalt arendaja pakutud tagasihelistamisele.

Nii saame idee, milliste juhtumitega meie komponent peab tegelema, aidates samal ajal visandada laienemist toetavat baasarhitektuuri.

Eraldi korduvkasutatav kasutajaliidese olek

Teatud kasutajaliidese interaktsioonid on erinevate komponentide hulgas tavalised, näiteks:

  • Luba / keela - nt. nupud, sisendid
  • Laienda / kahanda - nt. ahendamine, ripploendid
  • Näita / peida - üsna palju kõike

Neid omadusi kasutatakse sageli ainult visuaalse oleku juhtimiseks - loodetavasti.

Säilitage järjepidev nomenklatuur kõigis komponentides. Kõiki visuaalse olekuga seotud toiminguid saab teisaldada mixinisse.

/ * UIStateMixin * /
keela () {
  komplekt (see, 'keelatud', tõsi);
  tagastage see;
},
luba () {
  seatud (see, 'keelatud', vale ');
  tagastage see;
},

Iga meetod vastutab ainult konkreetse muutuja aktiveerimise eest ja tagastab praeguse aheldamise konteksti, näiteks:

nuppu
  .disable ()
  .showLoadingIndicator ();

Seda lähenemisviisi saab laiendada. See suudab aktsepteerida erinevaid kontekste ja kontrollida väliseid muutujaid, selle asemel, et kasutada sisemisi. Näiteks:

_getCurrentDisabledAttr () {
  return (isPresent (saada (see, 'keelatud'))))
    ? 'keelatud' / * väline parameeter * /
    : 'isDisabled'; / * Sisemine muutuja * /
},
luba (kontekst) {
  seatud (kontekst || see, see._getCurrentDisabledAttr (), vale);
  tagastage see;
}

Baasfunktsioonide võtmine

Iga komponent sisaldab teatud rutiine. Need rutiinid tuleb läbi viia sõltumata komponendi eesmärgist. Näiteks enne tagasikutsumist enne selle käivitamist kontrollitakse.

Neid vaikemeetodeid saab teisaldada ka oma miksinitesse, näiteks nii:

/ * BaseComponentMixin * /
_isCallbackValid (callbackName) {
  const tagasihelistamine = saada (see, callbackName);
  
  tagasi !! (isPresent (tagasihelistamine) && tagasihelistamise tüüp === 'funktsioon');
},
_handleCallback (tagasihelistamine, parameetrid) {
  if (! this._isCallbackValid (tagasihelistamine)) {
    viska uus viga (/ * teade * /);
  }
  this.sendAction (tagasihelistamine, parameetrid);
},

Ja siis komponentide hulka.

/ * Komponent * /
onClick (parameetrid) {
  this._handleCallback ('onClick', parameetrid);
}

See hoiab teie baasarhitektuuri ühtlasena. See võimaldab laiendada ja isegi integreerida kolmanda osapoole tarkvaraga. Kuid palun, ärge olge filosofeeriv abstraktsus.

Komponentide koostamine

Vältige funktsioonide ümberkirjutamist nii palju kui võimalik. Spetsialiseerumine on saavutatav. Seda saab teha kompositsiooni ja rühmitamise kaudu. Lisaks väiksemate komponentide tutistamisele uute komponentide loomiseks.

Näiteks:

Põhikomponendid: nupp, rippmenüü, sisend.
Rippmenüü => nupp + rippmenüü
Automaatne täitmine => sisestus + rippmenüü
Valige => sisend (ainult lugemiseks) + rippmenüü

Nii on igal komponendil oma kohustused. Igaüks haldab oma olekut ja parameetreid, samas kui ümbrise komponent töötleb oma konkreetset loogikat.

Murede eraldamine parimal viisil.

Mured jagavad

Keerukamate komponentide komponeerimisel on võimalus mured jagada. Mured saab jagada komponendi eri osade vahel

Oletame, et ehitame valitud komponendi.

{{vorm-valige köitmine = productId items = items}}
üksused = [
  {kirjeldus: 'toode nr 1', väärtus: 1},
  {kirjeldus: 'toode nr 2', väärtus: 2}
]

Sisemiselt on meil lihtne sisendkomponent ja rippmenüü.

{{vormi-sisestussiduv = _kirjeldus}}
{{ui rippmenüüd = üksused onSelect = (toiming 'selectItem')}}

Meie peamine ülesanne on kirjelduse kasutajale esitamine, kuid sellel pole meie rakenduse jaoks mingit tähendust - väärtus teeb seda.

Suvandi valimisel jagate objekti osadeks, saates sisemise muutuja kaudu kirjelduse alla meie sisendisse, lükates samal ajal väärtuse üles kontrollerile, värskendades seotud muutujat.

Seda mõistet saab rakendada komponentide puhul, kus seotud väärtust tuleb muuta, nagu näiteks arv, täidetakse automaatselt või valige väli. Ka kuupäevavõtjad saavad seda käitumist rakendada. Enne köidetud muutuja värskendamist saavad nad kuupäeva peita, kuvades kasutajale maskeeritud väärtuse.

Riskid suurenevad, kui muutuste keerukus suureneb. Liigse loogika või sündmuste toetamise kaudu - mõelge see enne selle lähenemisviisi rakendamist läbi.

Eelseaded vs uued komponendid

Mõnikord on arengu hõlbustamiseks vaja optimeerida komponente ja teenuseid. Need tarnitakse eelseadete või uute komponentidena.

Eelseaded on parameetrid. Teabe saamisel seadsid nad komponendile etteantud väärtused, lihtsustades selle deklareerimist. Uued komponendid on tavaliselt aga põhikomponentide spetsialiseeritumad versioonid.

Raske osa on teada, millal eelseadeid rakendada või uusi komponente luua. Kasutan selle otsuse tegemisel järgmisi juhiseid:

Millal eelseadeid luua?

1 - korduvad kasutusharjumused

On aegu, kus konkreetset komponenti kasutatakse samades parameetrites erinevates kohtades. Nendel juhtudel soovin eelistada eelseadistusi uute komponentide ees, eriti kui põhikomponendil on liiga palju parameetreid.

/ * Regulaarne rakendamine * /
{{vorm-automaatne täitmine
    siduv = toote ID
    url = "tooted" / * tõmmatav URL * /
    labelAttr = "description" / * siltidena kasutatud atribuuti * /
    valueAttr = "id" / * väärtusena kasutatakse atribuuti * /
    apiAttr = "toode" / * Param saadeti nõudmisel * /
}}
/ * Eelseaded * /
{{vorm-automaatne täitmine
    preset = "toode"
    siduv = toote ID
}}

Eelseatud väärtused seatakse ainult siis, kui parameetrit ei ole teavitatud, säilitades selle paindlikkuse.

/ * Eelseadete mooduli naiivne rakendamine * /
const presets = {
  toode: {
    URL: 'tooted',
    labelAttr: kirjeldus,
    valueAttr: „id”,
    apiAttr: 'toode',
  },
}
const attrs = presets [saada (see, 'eelseade')];
Object.keys (attrs) .forEach ((prop) => {
  if (! get (this, prop)) {
    komplekt (see, prop, attrs [prop]);
  }
});

See lähenemisviis vähendab teie komponendi kohandamiseks vajalikke teadmisi. Samal ajal hõlbustab see hooldust, võimaldades värskendada vaikeväärtusi ühes kohas.

2 - põhikomponent on liiga keeruline

Kui põhikomponent, mida kasutate konkreetsema komponendi loomiseks, võtab vastu liiga palju parameetreid. Seega tekitaks selle loomine teatavaid probleeme. Näiteks:

  • Peaksite sisestama kõige rohkem - kui mitte kõiki - parameetreid uuest komponendist põhikomponendini. Kuna sellest tuleneb üha enam komponente, kajastaksid kõik põhikomponendi värskendused tohutul hulgal muudatusi. Seega on vea esinemissagedus kõrgem.
  • Mida rohkem komponente luuakse, seda raskem on erinevaid nüansse dokumenteerida ja meelde jätta. See kehtib eriti uute arendajate kohta.

Millal luua uusi komponente

1 - funktsionaalsuse laiendamine

Funktsionaalsuse laiendamisel lihtsamast komponendist on otstarbekas luua uus komponent. See aitab teil vältida komponendipõhise loogika lekkimist teise komponendi juurde. See on eriti kasulik lisakäitumise rakendamisel.

/ * Deklaratsioon * /
{{ui-nupu rippmenüü = üksused}}
/* Kapoti all */
{{# ui-nupp onClick = (toiming 'toggleDropdown')}}
  {{silt}}  
{{/ ui-button}}
{{#if isExpanded}}
  {{ui rippmenüüd = üksused}}
{{/ kui}}

Ülaltoodud näites kasutatakse nupukomponenti. See laiendab selle paigutust fikseeritud ikooni toetamiseks, lisades samal ajal rippmenüü ja nähtavuse oleku.

2 - kaunistusparameetrid

Uute komponentide loomiseks on veel üks võimalik põhjus. See on siis, kui on vaja kontrollida parameetrite saadavust või kaunistada vaikeväärtusi.

/ * Deklaratsioon * /
{{form-datepicker onFocus = (toiming 'doSomething')}}
/* Kapoti all */
{{form-input onFocus = (tegevus '_onFocus')}}
_onFocus () {
  $ (see element)
    .find ('sisend')
    .vali (); / * Valige fookuses välja väärtus * /
  this._handleCallback ('onFocus'); / * Käivitab parameetri tagasihelistamise * /
}

Selles näites anti komponendile funktsioon, mis oli mõeldud välja fokuseerimisel.

Sisemiselt, selle asemel, et tagasihelistamine otse põhikomponendile edastada, läbib see sisemise funktsiooni. See täidab konkreetse ülesande (valides välja väärtuse) ja helistab siis antud tagasihelistamisele.

See ei suuna kõiki põhisisendi komponendi aktsepteeritud parameetreid. See aitab kontrollida teatud funktsioonide ulatust. Samuti välditakse tarbetuid valideerimisi.

Minu puhul asendas onBluri sündmus teise sündmusega - onChange. See käivitub, kui kasutaja kas täidab välja või valib kalendrist kuupäeva.

Järeldus

Komponentide ehitamisel arvestage nii oma küljega kui ka sellega, kes seda komponenti oma igapäevaelus kasutab. Nii võidavad kõik.

Parima tulemuse saab see, kui kõik rühmas teevad kõik, mis on parim nii tema enda kui ka rühma jaoks - John Nash

Ärge häbenege ka tagasisidet küsida. Leiate alati midagi, mille kallal saaks töötada.

Tarkvarainseneri oskuste veelgi teravdamiseks soovitan järgida Eric Elliotti sarja „Tarkvara komponeerimine“. See on fantastiline!

Noh, ma loodan, et teile artikkel meeldis. Võtke need kontseptsioonid kasutusele, tehke oma ideedest ja jagage neid meiega!

Samuti võtke julgesti ühendust minuga twitteris @gcolombo_! Mulle meeldiks kuulda teie arvamust ja isegi koostööd teha.

Aitäh!