Uživatelské rozhraní založené na komponentách je v dnešní době v módě. Věděli jste, že web má svůj vlastní modul nativních komponent, který nevyžaduje použití žádných knihoven? Pravdivý příběh! Můžete psát, publikovat a znovu používat jednosouborové komponenty, které budou fungovat v jakémkoli* dobrém prohlížeči a v jakémkoli rámci (pokud je to vaše taška).
V našem posledním příspěvku jsme se naučili psát jednosouborové komponenty s ničím jiným než JavaScriptem a DOM API.
Dnes se ponoříme do původní knihovny webových komponent:Polymer. Zrefaktorujeme <lazy-image>
komponent, který jsme vytvořili minule, abychom využili užitečných funkcí Polymeru. Naučíme se také skládat celé aplikace z komponent na bázi polymerů pomocí jejich výrazného systému šablon a obousměrné vazby. Podíváme se na některé fantastické hotové papírové prvky publikované týmem Polymer. A nakonec prozkoumáme některé užitečné nástroje projektu Polymer a zjistíme, jak jsou užitečné pro jakýkoli projekt webových komponent, nejen pro aplikace Polymer.
- Projekt Polymer
- Refaktoring
<lazy-image>
- Vlastnosti
- Šablony datových vazeb
- Další funkce polymeru
- Pokročilé vázání dat
- Pozorovatelé a vypočítané vlastnosti
- Deskriptory vlastností
- Pomocné prvky
- Skládání polymerových aplikací
- Papírové prvky
- Polymer Tools
prpl-server
- Polymer CLI
- WebComponents.org
The Polymer Project
Projekt Polymer začal již v roce 2012/2013 s cílem posunout možnosti webové platformy. Legenda praví, že hluboko v útrobách Googleplexu svolala skupina inženýrů prohlížeče Chrome tajnou seanci se skupinou webových vývojářů, aby zmapovali budoucí směřování webu jako celku.
Inženýři prohlížeče požádali vývojáře webu, aby jim řekli, jak chtějí, aby webový vývoj vypadal za pět let, a pak se pustili do jeho budování. Výsledkem bylo první vydání knihovny Polymer a začátek příběhu moderních webových komponent.
Od té doby se projekt Polymer uzavřel tak, že je nyní možné psát webové komponenty bez použití knihovny Polymer. Ale Polymer Project stále žije. Udržují různé návrhy webových platforem a obhajují typ vývoje webu více založený na standardech, než je v současnosti populární.
Na druhé straně knihovna Polymer se od té doby stala pouze jednou z mnoha alternativ pro faktoring webových komponent a aplikací založených na komponentách.
Nepleťte si tedy dvě věci. Projekt je o platformě obecně, Knihovně je o pomoci vám při sestavování komponent.
Refaktoring <lazy-image>
Pojďme se tedy ponořit! A protože jsme již vyvinuli náš <lazy-image>
vanilkovou složkou, použijme ji jako základ také pro zkoumání Polymeru.
Náš první krok při refaktorování <lazy-image>
bude instalace a import knihovny Polymer.
npm i -S @polymer/polymer
Také trochu přejmenujeme naši součást, aby nám pomohla udržet hlavu rovně:
import { PolymerElement, html } from '@polymer/polymer'
const tagName = 'polymer-lazy-image';
class PolymerLazyImage extends PolymerElement {
/* ... */
}
customElements.define(tagName, PolymerLazyImage)
Polymer 3.0 a papírové prvky vyžadují, abychom aplikovali transformaci na všechny specifikátory modulu, buď v kroku sestavení, nebo jako běh serveru. Použijeme polymer serve
, který pro nás transformuje holé specifikátory za běhu.
npm i -D polymer-cli
npx polymer serve
Dalším důležitým krokem, který bychom nyní měli udělat, než se pustíme do dalšího machrování, je zavolat super
verze všech našich zpětných volání během životního cyklu.
connectedCallback() {
super.connectedCallback();
// ...
}
disconnectedCallback() {
super.disconnectedCallback();
// ...
}
Pokud tak neučiníte, způsobí to problémy, protože PolymerElement
základní třída musí pracovat, když se dějí věci životního cyklu. Práce jako manipulace s polyfilly, kterou už nemusíme dělat ručně...
connectedCallback() {
super.connectedCallback();
this.setAttribute('role', 'presentation');
if ('IntersectionObserver' in window) this.initIntersectionObserver();
else this.intersecting = true;
}
Můžeme ztratit všechny shadowRoot
- a ShadyCSS
-související kód nyní, včetně updateShadyStyles
, protože Polymer to zvládne za nás. Pěkný! Práce s knihovnami nám vzala jeden stres – podporu polyfillů – z naší mysli.
Vlastnosti
Polymer vám umožňuje deklarovat vlastnosti vašeho prvku staticky, a mám na mysli „staticky“ ve smyslu obou static get
a „v době psaní“. Když deklarujete vlastnost v tomto bloku, Polymer se postará o synchronizaci atributů a vlastností za vás. To znamená, že když src
je nastaven atribut na našem prvku, Polymer automaticky aktualizuje src
vlastnost na instanci prvku.
Nyní tedy můžeme smazat naše attributeChangedCallback
, safeSetAttribute
a všechny naše gettery a nastavovače a nahraďte je statickou mapou vlastností s některými speciálními deskriptory specifickými pro polymery.
static get properties() {
return {
/** Image alt-text. */
alt: String,
/**
* Whether the element is on screen.
* @type {Boolean}
*/
intersecting: {
type: Boolean,
reflectToAttribute: true,
notify: true,
},
/** Image URI. */
src: String,
};
}
Polymer se standardně váže na vlastnosti, nikoli na atributy. To znamená, že pokud se navážete na jednu z vlastností svého prvku v šabloně polymeru hostitelského prvku, nemusí se to nutně zobrazit jako atribut prvku. Nastavení reflectToAttribute
boolean na deskriptoru vlastnosti zajišťuje, že kdykoli se vlastnost změní, Polymer také nastaví příslušný atribut prvku. Nemějte však obavy, i když deklarujete vlastnost pomocí konstruktoru jako propName: String
, změny atributů vždy aktualizují přidruženou vlastnost, bez ohledu na to, zda nastavíte reflectToAttribute
.
Poznámka :Polymer převede názvy vlastností camelCase na názvy atributů malých a velkých písmen a naopak. To je mimochodem důvod, proč knihovna Polymer ve skutečnosti selhává v některých testech „Custom Elements Everywhere“.
notify
boolean způsobí, že váš prvek odešle vlastní událost pokaždé, když se vaše vlastnost změní. Událost se bude jmenovat property-name-changed
např. intersecting-changed
pro intersecting
vlastnost a bude mít tak, jak je detail
vlastnost objekt obsahující klíč value
která ukazuje na novou hodnotu vašeho majetku.
lazyImage.addEventListener('intersecting-changed', event => {
console.log(event.detail.value) // value of 'intersecting';
})
To je základ dvoucestného systému vázání Polymer. Zde to není nezbytně nutné, ale můžeme tyto události také vystavit pro případ, že by uživatel chtěl svázat intersecting
obrázku stav až do uzavírající komponenty.
Nyní tedy můžeme také odstranit setIntersecting
metodu, protože s pomocí naší mapy nemovitostí a šablonovacího systému Polymer ji nebudeme potřebovat.
Více o deskriptorech vlastností Polymeru budeme mít později.
Šablony datových vazeb
Šablony prvku Polymer 3 definujeme statickým template
getter, který vrací tagovaný literál šablony.
static get template() {
return html`
I'm the Template!
`;
}
Polymerové šablony mají speciální syntaxi připomínající řídítka nebo knír. Jednosměrné (data-down) vazby jsou vytvořeny pomocí double-[[hranaté závorky]] a obousměrné (data-up) vazby jsou vytvořeny pomocí double-{{
složené závorky}}
.
<some-input input="{{myInput}}"></some-input>
<some-element
some-property="[[myInput]]"
some-attribute$="[[myAttribute]]"
></some-element>
V tomto příkladu vždy, když <some-input>
spustí input-changed
událost, prvek hostitele aktualizuje someProperty
vlastnost na <some-element>
. Z hlediska JS je to jednoduché zadání:someElementInstance.someProperty = this.myInput
.
Pokud se chcete svázat s atributem, místo vlastnosti připojte $
znak do vazby:kdykoli myOtherProp
změny, some-attribute
na <some-element>
se aktualizuje:someElementInstance.setAttribute('some-attribute', this.myOtherProp)
.
Podobně vždy, když input-changed
vlastní událost se spustí na <some-input>
, myInput
vlastnost na hostitelské komponentě bude nastavena na detail.value
události vlastnost.
V našem <polymer-lazy-image>
šablony, nepoužíváme žádnou obousměrnou vazbu, takže zůstaneme u hranatých závorek.
aria-hidden
atribut představuje malou výzvu. Polymer spojuje booleovské hodnoty s atributem s setAttribute(name, '')
a removeAttribute(name)
. Ale od aria-hidden
musí převzít řetězcové literály "true"
nebo "false"
, nemůžeme to jen svázat s booleovskou hodnotou intersecting
. <img/>
src
je podobně zajímavé. Ve skutečnosti jej chceme nastavit až poté, co se prvek protne. K tomu budeme muset vypočítat vlastnost src na obrázku na základě stavu intersecting
vlastnost.
Polymerové šablony mohou obsahovat počítané vazby . Ty jsou vázány na návratovou hodnotu zvolené metody.
<img id="image"
aria-hidden$="[[computeImageAriaHidden(intersecting)]]"
src="[[computeSrc(intersecting, src)]]"
alt$="[[alt]]"
/>
Co je s touto syntaxí podobnou funkci uvnitř našich vazebných výrazů? To říká Polymeru, kterou metodu prvku spustit a kdy. Spustí se pokaždé, když jsou pozorovány změny jeho závislostí (tj. „předané argumenty“ ve výrazu vazby), čímž se vazba aktualizuje o vrácenou hodnotu.
Všimněte si také, že jsme vázáni na src
vlastnictví na obrázku, nikoli na atributu . Je to proto, abyste se nepokoušeli načíst obrázek na adrese URL "undefined"
.
computeSrc(intersecting, src) {
// when `intersecting` or `src` change,
return intersecting ? src : undefined;
}
computeImageAriaHidden(intersecting) {
// when `intersecting` changes,
return String(!intersecting);
}
Nenechte se však zmást, nejedná se o výrazy JavaScript, takže nemůžete zadat žádnou hodnotu, kterou chcete:[[computeImageAriaHidden(!intersecting)]]
nefunguje, ani [[computeImageAriaHidden(this.getAttribute('aria-hidden'))]]
Nyní jen mírně upravíme naši mapu vlastností a styly, abychom zohlednili změny v API našeho prvku:
static get properties() {
return {
// ...
/** Whether the element is intersecting. */
intersecting: Boolean,
/**
* Whether the image has loaded.
* @type {Boolean}
*/
loaded: {
type: Boolean,
reflectToAttribute: true,
value: false,
},
};
}
<style>
/* ... */
#placeholder ::slotted(*),
:host([loaded]) #image {
opacity: 1;
}
#image,
:host([loaded]) #placeholder ::slotted(*) {
opacity: 0;
}
</style>
<div id="placeholder" aria-hidden$="[[computePlaceholderAriaHidden(intersecting)]]">
<slot name="placeholder"></slot>
</div>
<img id="image"
aria-hidden$="[[computeImageAriaHidden(intersecting)]]"
src="[[computeSrc(intersecting, src)]]"
alt$="[[alt]]"
on-load="onLoad"
/>
Podařilo se nám tedy podstatně snížit standardizovaný obsah v naší komponentě a zkrátit část přebytečné logiky jejím zahrnutím do naší šablony, i když s několika poněkud únavnými výpočetními pomocníky pro vazby.
Zde je náš dokončený <polymer-lazy-image>
modul:
import { PolymerElement, html } from '@polymer/polymer';
const isIntersecting = ({isIntersecting}) => isIntersecting;
const tagName = 'polymer-lazy-image';
class PolymerLazyImage extends PolymerElement {
static get template() {
return html`
<style>
:host {
position: relative;
}
#image,
#placeholder ::slotted(*) {
position: absolute;
top: 0;
left: 0;
transition:
opacity
var(--lazy-image-fade-duration, 0.3s)
var(--lazy-image-fade-easing, ease);
object-fit: var(--lazy-image-fit, contain);
width: var(--lazy-image-width, 100%);
height: var(--lazy-image-height, 100%);
}
#placeholder ::slotted(*),
:host([loaded]) #image {
opacity: 1;
}
#image,
:host([loaded]) #placeholder ::slotted(*) {
opacity: 0;
}
</style>
<div id="placeholder" aria-hidden$="[[computePlaceholderAriaHidden(intersecting)]]">
<slot name="placeholder"></slot>
</div>
<img id="image"
aria-hidden$="[[computeImageAriaHidden(intersecting)]]"
src="[[computeSrc(intersecting, src)]]"
alt$="[[alt]]"
on-load="onLoad"
/>
`;
}
static get properties() {
return {
/** Image alt-text. */
alt: String,
/** Whether the element is on screen. */
intersecting: Boolean,
/** Image URI. */
src: String,
/**
* Whether the image has loaded.
* @type {Boolean}
*/
loaded: {
type: Boolean,
reflectToAttribute: true,
value: false,
},
};
}
constructor() {
super();
this.observerCallback = this.observerCallback.bind(this);
}
connectedCallback() {
super.connectedCallback();
// Remove the wrapping `<lazy-image>` element from the a11y tree.
this.setAttribute('role', 'presentation');
// if IntersectionObserver is available, initialize it.
if ('IntersectionObserver' in window) this.initIntersectionObserver();
// if IntersectionObserver is unavailable, simply load the image.
else this.intersecting = true;
}
disconnectedCallback() {
super.disconnectedCallback();
this.disconnectObserver();
}
/**
* Loads the img when IntersectionObserver fires.
* @param {Boolean} intersecting
* @param {String} src
* @return {String}
*/
computeSrc(intersecting, src) {
return intersecting ? src : undefined;
}
/**
* "true" when intersecting, "false" otherwise.
* @protected
*/
computePlaceholderAriaHidden(intersecting) {
return String(intersecting);
}
/**
* "false" when intersecting, "true" otherwise.
* @protected
*/
computeImageAriaHidden(intersecting) {
return String(!intersecting);
}
/** @protected */
onLoad() {
this.loaded = true;
}
/**
* Sets the `intersecting` property when the element is on screen.
* @param {[IntersectionObserverEntry]} entries
* @protected
*/
observerCallback(entries) {
if (entries.some(isIntersecting)) this.intersecting = true;
}
/**
* Initializes the IntersectionObserver when the element instantiates.
* @protected
*/
initIntersectionObserver() {
if (this.observer) return;
// Start loading the image 10px before it appears on screen
const rootMargin = '10px';
this.observer = new IntersectionObserver(this.observerCallback, { rootMargin });
this.observer.observe(this);
}
/**
* Disconnects and unloads the IntersectionObserver.
* @protected
*/
disconnectObserver() {
this.observer.disconnect();
this.observer = null;
delete this.observer;
}
}
customElements.define(tagName, PolymerLazyImage);
Podívejte se na rozdíl mezi vanilkou a polymerovou verzí a podívejte se, jak komponenta funguje:
Další funkce polymeru
Polymer nabízí více, než může náš jednoduchý příklad prvku snadno ukázat. Malým příkladem je způsob, jakým Polymer mapuje všechny id
'd prvků ve vaší šabloně na objekt s názvem $
:
<paper-button id="button">Button!</paper-button>
<paper-input id="input" label="Input!"></paper-input>
connectedCallback() {
console.log(this.$.button.textContent) // "Button!"
this.$.input.addEventListener('value-changed', breakTheInternet);
}
Pokročilé vázání dat
Polymer se také může vázat na vlastnosti hostitele z událostí nepolymerních prvků se speciální syntaxí:
<video current-time="{{videoTime::timeupdate}}"/>
To znamená, "když timeupdate
událost se spustí, přiřaďte místní videoTime
vlastnost na currentTime
prvku videa ".
V pozdější iteraci <polymer-lazy-image>
, můžeme tyto druhy vazeb použít k synchronizaci interního <img>
vlastnosti s našimi vlastními.
Chcete-li se dozvědět více o systému vázání dat Polymeru, přečtěte si dokumenty.
Pozorovatelé a vypočítané vlastnosti
Vypočtené vlastnosti a vazby jsou specializovanými případy pozorovatelů Polymeru . Jednoduchý pozorovatel vypadá takto:
static get properties() {
return {
observed: {
type: String,
observer: 'observedChanged',
},
};
}
observedChanged(observed, oldVal) {
console.log(`${ observed } was ${ oldVal }`);
}
Můžete také definovat komplexní pozorovatele, kteří využívají více závislostí nebo hluboce pozorují objekty nebo pole.
static get properties() {
return {
observed: Object,
message: {
type: String,
value: 'A property of observed has changed',
},
};
}
static get observers() {
return [
// careful: deep observers are performance intensive!
'observedChanged(message, observed.*)'
],
}
observedChanged(message, { path, value, base }) {
// path: the path through the object where the change occurred
// value: the new value at that path
// base: the root object e.g. `observed`
console.log(message, path + ': ' + value);
}
Můžete také nastavit počítané vlastnosti, podobné počítaným vazbám:
static get properties() {
return {
theString: String,
theLength: {
type: Number,
computed: 'computeTheLength(theString)',
},
};
}
computeTheLength(theString) {
return theString.length;
}
V takovém případě theLength
se aktualizuje podle computeTheLength
kdykoli theString
změny.
Tyto vypočítané vlastnosti pak mohou být svázány s vaší šablonou jako každá normální vlastnost.
<span>[[theString]] has [[theLength]] characters</span>
Přečtěte si vše o pozorovatelích polymeru v docs.
Popisy vlastností
Již jsme viděli, jak můžeme nastavit reflectToAttribute
a notify
ovlivnit vnější svět při aktualizaci našich hodnot a jak nastavit jednoduché pozorovatele pomocí observer
deskriptor.
Můžete také nastavit výchozí hodnotu pomocí value
, který má buď doslovnou hodnotu, nebo funkci.
static get properties() {
return {
prop: {
type: String,
value: '🚣♂️'
},
things: {
type: Array,
value: () => [],
},
};
}
Buďte opatrní! Když chcete nastavit výchozí hodnotu s typem reference jako Array
nebo Object
, nezapomeňte předat funkci nebo jinak každou instanci vašeho prvku bude sdílet stejnou referenci.
value
přiřazení jsou nastavena jednou při inicializaci komponenty a poté se znovu neaktualizují. Pokud potřebujete po připojení dynamicky nastavit vlastnosti, použijte vypočítané vlastnosti nebo pozorovatele.
Pomocné prvky
Polymer je dodáván s několika pomocnými prvky, které můžete použít ve svých šablonách, abyste snížili množství nezbytného JavaScriptu, který musíte psát. Dva nejčastěji používané jsou <dom-repeat>
pro iteraci seznamů a výstup DOM a <dom-if>
pro podmíněné vykreslování:
<!-- Will output a new article with h2 and img for each post -->
<dom-repeat items="[[posts]]" as="post">
<template>
<article>
<h2>[[post.title]]</h2>
<img src$="[[post.picture]]">
</article>
</template>
</dom-repeat>
<!-- Will only render it's template if conditionDepending(someProp, another) is truthy -->
<dom-if if="[[conditionDepending(someProp, another)]]">
<template>
I'm a very lucky textNode to have [[someProp]] and [[another]] on my side.
</template>
</dom-if>
Chcete-li tyto pomocníky používat, nezapomeňte je importovat
import '@polymer/polymer/lib/elements/dom-repeat.js';
import '@polymer/polymer/lib/elements/dom-if.js';
Další informace o pomocných prvcích naleznete v dokumentech Polymer.
Skládání aplikací Polymer
Polymer opravdu září, pokud jde o faktoring celých aplikací. Projekt Polymer byl průkopníkem docela progresivního a zjevně speciálního (pardon) druhu deklarativní struktury aplikací postavené převážně na prvcích HTML. Přístup Polymer dělá ze „všeho prvek prvek“ a využívá vestavěnou složitelnost HTML. Například je tu <iron-ajax>
prvek, který může načíst zdroje a vystavit je datové vazbě Polymeru.
<iron-ajax auto
url="/api/posts"
handle-as="json"
last-response="{{posts}}"></iron-ajax>
<dom-repeat items="[[posts]]" as="post">
<template>
<article>
<h2>[[post.title]]</h2>
<img hidden$="[[!post.cover]]" src$="[[post.cover]]">
[[post.body]]
</article>
</template>
</dom-repeat>
Ale podle mého skromného názoru je nejlepším příkladem tohoto přístupu <app-route>
prvek a myšlenka zapouzdřeného směrování:
<!-- <app-shell> template -->
<!-- Capture and expose address-bar changes -->
<app-location route="{{route}}"></app-location>
<app-route route="[[route]]"
data="{{routeData}}"
tail="{{pageTail}}"
pattern="/:page"></app-route>
<!-- Composed routing! -->
<app-route route="[[tail]]"
data="{{itemData}}"
tail="{{itemTail}}"
pattern="/:itemId"></app-route>
<iron-pages selected="{{routeData.page}}" attr-for-selected="name">
<app-master name="master"></app-master>
<app-detail name="detail"
item-id="[[itemData.itemId]]"
route="[[itemTail]]"></app-detail>
</iron-pages>
Pomocí prvků app-route a iron-pages máme kompletní řešení pro směrování, které skryje a zobrazí obsah na základě adresy URL a dokonce těmto komponentám zobrazení předá data související s trasou.
A od <app-route>
trvá to route
vlastnost jako data, která nejsou přímo svázána s window.location
, můžete předat části trasy dolů do podřízených zobrazení a nechat je spravovat svůj vlastní vnitřní stav pomocí vlastního <app-route>
děti. Skvělé!
<!-- <app-detail> template -->
<app-route route="[[route]]"
data="{{routeData}}"
pattern="/:editing"></app-route>
<item-detail hidden$="[[routeData.editing]]"></item-detail>
<item-editor hidden$="[[!routeData.editing]]"></item-editor>
<paper-checkbox checked="{{routeData.editing}}">Editing</paper-checkbox>
Skvělý koncept!
**Všimněte si**, že kvůli stručnosti se v tomto příkladu vážeme přímo na podvlastnosti `routeData`, ale ve skutečném projektu bychom přidali některé pomocné metody pro výpočet mezilehlé vlastnosti `page` z `routeData '.Plně realizovaný příklad tohoto typu architektury aplikací najdete v úctyhodném Polymer Starter Kit na GitHubu.
Polymer/polymer-starter-kit
Výchozí bod pro aplikace Polymer
Polymer App Toolbox – Starter Kit
Tato šablona je výchozím bodem pro vytváření aplikací pomocí rozložení založeného na zásuvkách. Rozvržení zajišťuje app-layout
prvky.
Tato šablona spolu s polymer-cli
toolchain, také demonstruje použití „vzoru PRPL“ Tento vzor umožňuje rychlé první doručení a interakci s obsahem na počáteční trase požadované uživatelem, spolu s rychlou následnou navigací pomocí předběžného ukládání zbývajících komponent požadovaných aplikací do mezipaměti a jejich postupným načítáním na vyžádání. jak uživatel prochází aplikací.
Vzor PRPL, v kostce:
- Push komponenty požadované pro počáteční trasu
- Vykreslit počáteční trasa ASAP
- Předběžné ukládání do mezipaměti komponenty pro zbývající trasy
- Lazy-load a postupně upgradovat další trasy na vyžádání
Nastavení
Předpoklady
Nainstalujte Polymer CLI pomocí npm (předpokládáme, že máte předinstalovaný node.js).
npm install -g polymer-cli
Inicializovat projekt ze šablony
mkdir my-app
cd my-app
polymer init polymer-3-starter-kit
Spusťte vývojový server
Tento příkaz slouží…
Zobrazit na GitHubuPapírové prvky
Nebyl by to příspěvek na blogu o Polymeru, kdybychom nezmínili Paper Elements, sadu materiálových designových UI komponent publikovanou Polymer Project. Ale také bychom udělali obrovskou chybu, kdybychom jednu věc nevyjasnili:
PaperElements != Polymer;
Knihovnu polymerů můžete použít bez použití papírových prvků a můžete použít papírové prvky v pohodě bez použití knihovny polymerů!
<head>
<script type="module" src="https://unpkg.com/@polymer/paper-checkbox/paper-checkbox.js?module"></script>
<script type="module" src="https://unpkg.com/@polymer/paper-card/paper-card.js?module"></script>
<script type="module" src="https://unpkg.com/@polymer/paper-button/paper-button.js?module"></script>
</head>
<body>
<paper-card heading="Am I Checked?">
<div class="card-content">
Output: <span id="output">Not Checked</span>
</div>
<div class="card-actions">
<paper-checkbox id="input">Check me!</paper-checkbox>
<paper-button raised disabled id="button">Reset</paper-button>
</div>
</paper-card>
<script>
const onClick = () => input.checked = false;
const onInput = ({detail: { value }}) => {
output.textContent = value ? 'Checked' : 'Not Checked';
button.disabled = !value;
}
input.addEventListener('checked-changed', onInput);
button.addEventListener('click', onClick);
</script>
</body>
Jediné, co zde ztrácíme, je schopnost používat systém datové vazby Polymeru. Ale - uhodli jste správně - existuje pro to prvek, nazvaný <dom-bind>
Pokud chcete bez problémů zohlednit uživatelské rozhraní založené na materiálovém designu – vyzkoušejte papírové prvky.
Polymer Tools
The Polymer Project – kromě jejich obhajovací práce, JS a knihoven komponent a návrhů standardů – také publikuje řadu nástrojů, které vám pomohou vytvořit, publikovat a poskytovat vaše aplikace a komponenty.
prpl-server
Tým Chrome vyvinul vzor PRPL jako osvědčený postup pro psaní a poskytování výkonných webových aplikací. prpl-server
usnadňuje poskytování nejmenšího efektivního balíčku schopným prohlížečům a přitom stále podporuje starší prohlížeče s většími balíčky. K dispozici je hotová binární i expresní middlewarová knihovna. Zkuste to.
Polymer CLI
Vue CLI vám pomáhá vyvíjet aplikace Vue. Angular CLI vám pomáhá vyvíjet aplikace Angular. create-react-app
vám pomůže vyvíjet aplikace React.
Polymer CLI vám pomůže vyvinout web aplikace.
Pravda, nabízí šablony pro prvky a aplikace Polymer 3, ale to není vše. polymer build
a polymer serve
příkazy vytvoří a obslouží všechny aplikace webových komponent. Transpilace je volitelná. Ve skutečnosti v podstatě jediná věc, kterou CLI udělá s vaším kódem, je nahrazení specifikátorů holých modulů jako import { PolymerElement } from '@polymer/polymer';
na relativní adresy URL, které může prohlížeč načíst přímo.
To jo. To je přesně to, o čem mluvím. Až budete mít příště projekt aplikace, zvažte jeho zohlednění pomocí webových komponent a rozhraní Polymer CLI.
Ale pokud chcete transpilovat pro starší prohlížeče (viz prpl-server
výše), můžete definovat builds
sekce polymer.json
:
{
"root": "~/projects/my-project",
"entrypoint": "index.html",
"shell": "src/my-project.js",
"sources": [
"src/my-project.js",
"manifest/**",
"package.json"
],
"builds": [{
"name": "es5prod",
"preset": "es5-bundled",
"addServiceWorker": true
}, {
"name": "es6prod",
"preset": "es6-unbundled",
"addServiceWorker": true
}, {
"name": "dev",
"addServiceWorker": false,
"js": {"minify": false, "compile": false},
"css": {"minify": false},
"html": {"minify": false},
"bundle": false,
"addPushManifest": false
}]
}
Poté stačí nakonfigurovat prpl-server
aby obsluhoval es6prod
do moderních prohlížečů a es5prod
do IE a kamarády a vyrazíte na závody.
Přečtěte si dokumenty, doktore!
WebComponents.org
Než odběhnete implementovat to <super-button>
máte na mysli, proč nedat hledat na webcomponents.org, největším adresáři webových komponent.
Každý prvek je zobrazen se svou dokumentací, veřejným rozhraním API a způsobem instalace. Najdete zde také odkazy na npm a github.
Pokud jste autor komponent, neváhejte! Publikujte své komponenty, aby z nich měli užitek ostatní.
Závěry
Polymerová knihovna nepopiratelně předběhla dobu. Chtělo to přístup vyžadovat lepší webovou platformu a pak to udělat realitou, namísto pouhého obcházení omezení platformy.
Nyní, když jsou webové komponenty široce podporovány, má knihovna Polymer stále místo v naší sadě nástrojů pro webové vývojáře? Určitě ano! Některé projekty se přirozeně hodí k deklarativnímu stylu Polymeru. Některé týmy zjistí, jak mohou návrháři a autoři dokumentů dělat práci vývojářů s expresivním systémem vazby Polymer.
Není to všechno ☀️ a 🌹🌹 i když. S rozvojem platformy a širší webové komunity se vyvíjely i priority projektu Polymer. Polymer 3 bude pravděpodobně posledním velkým vydáním knihovny a stejně tak série 3.0 bude posledním vydáním papírových prvků.
Pojďme si tedy zopakovat některé výhody a nevýhody knihovny Polymer:
Výhody | Nevýhody |
---|---|
Expresivní systém šablon | Nelze předat JS přímo do šablon |
Pozorovatelé a vypočítané vlastnosti, deklarativní posluchači událostí | Velký řetězec závislostí podněcuje větší aplikace pouze s polymerem |
Super skvělý a jedinečný přístup k deklarativní struktuře aplikace | V dobrém i ve zlém, tento jedinečný deklarativní styl není tak populární jako jiné architektury |
Vyspělá knihovna a sada komponent. Vyzkoušeno, otestováno a pravdivé | Polymer.js je zcela zastaralý a nebude dostávat nové funkce, dokud nebude rozvětvený |
Znamená to tedy pro Web Components konec? Sakra Ne! Polymer není zdaleka jedinou hrou ve městě. Odlehčená, deklarativní knihovna šablon JS s názvem lit-html
a základní třídu vlastních prvků, která ji využívá, nazvanou LitElement
jsou nové horkost. Dá-li Bůh, probereme je v příštím díle.
Tak se uvidíme 😊
Chtěli byste osobní mentoring na některé z témat, která jsou zde popsána?
Poděkování
Děkuji bez zvláštního pořadí Pascalu Schilpovi a @ruphin za jejich návrhy a opravy.
Podívejte se na další článek ze série