Веб-компоненты — это новая эра веб-разработки и почувствовать ее мощь можно уже сегодня при помощи Polymer от Google. Вы можете создавать свои собственные «элементы» (тэги), содержащие шаблон и инкапсулированные стили и логику (js), а так же воспользоваться богатой коллекцией уже готовых элементов.
Что такое Polymer?
Polymer это библиотека (сами они называют это, набором полифилов и синтаксического сахара) для создания и использования веб-компонент. А веб-компоненты это некий набор стандартов W3C, который в будущем будет поддерживаться уже поддерживается некоторыми браузерами. Если совсем по-простому, то веб-компонента это некий выделенный в отдельный блок кусок html кода с шаблонированием, стилями и логикой. Это позволяет повысить структурированность вашего html кода, повысить читаемость и повторное использование. Один раз написал (или выбрал из стандартных) и используй везде.
Если вы думаете, что html5 изменил веб, то подождите и увидите, что сделают Веб-компоненты. © чей-то.
Проникнуться идеей веб-компонент можно на webcomponents.org. Поковыряться в чужих компонентах можно на component.kitchen.
Ну и еще существует большая вероятность, что Polymer-ное виденье будущего станет реальностью, и вы в будущем просто отключите Polymer и все продолжит работать нативно. Как мы понимаем, такие компании, как Google и Mozilla (они разрабатывают похожий x-tag) могут менять будущее веба.
Инфраструктура
Для того, чтобы теорию подкрепить практикой, нам нужна инфраструктура. Самый простой способ создать ее – это yeoman и генератор Polymer для него (и конечно нужен Bower). Ниже необходимые команды (уже установленное у вас — пропускайте).
npm install -g bower
npm install -g yo
npm install -g generator-polymer
mkdir my-project
cd my-project
yo polymer
В результате получаем начальный скелет приложения с парой собственных элементов, а также папку со всей коллекцией готовых элементов. Для того, чтобы посмотреть, как это выглядит в работе, нужно запустить сервер.
grunt serve
После запуска откроется браузер и Вы увидите такую картинку:
Итак, когда инфраструктура налажена, приступим к изучению:
Использование готовых компонент и элементов.
Polymer содержит две основные коллекции элементов:
- Core-elements – это набор элементов, включающий визуальные элементы (панельки, кнопки, инпуты и пр) и не визуальные элементы (ajax, localstorage и т.д ).
- Paper-elements – это набор элементов, реализующий новый material design, последнее время широко используемый Google.
Для использования элементов в index.html
должен быть подключен (у нас уже все подключено) platform.js
:
<script src="bower_components/platform/platform.js"></script>
Также нужно импортировать при помощи тега <link>
нужные нам элементы до их использования:
<link rel="import" href="bower_components/[папка]/[элемент].html">
Потом просто вставляете нужные теги в ваш код и все:
<core-scaffold>
<core-header-panel mode="seamed" navigation flex>
<core-toolbar></core-toolbar>
<core-menu valueattr="label">
<core-item icon="settings" label="Item1"></core-item>
<core-item icon="settings" label="Item2"></core-item>
</core-menu>
</core-header-panel>
<google-map></google-map>
</core-scaffold>
Для API Google есть готовые компоненты, например <google-map></google-map>
. Это позволяет легко встраивать сервисы Google в наше приложение. Смотрите список компонент на googlewebcomponents.github.io.
По быстрому накидать готовых компонент на страницу, подправить стили и js код, посмотреть, как это все выглядит можно при помощи Design tool. С помощью нее можно потом сохранить полученный код как Github Gist.
Вот небольшое видео о работе в этом «редакторе».
Создание элементов
Это, пожалуй, самая главная фишка веб-компонент и Polymer-а (по крайней мере для меня). Это похоже на директиву Angular, только с нормальным html со стилями и логикой. При чем все это изолированно и работает в своем скопе и ни кто из вне ничего не поломает.
Выглядит это так: (я создам элемент <habrauser-card>
. Начну с пустого habrauser-card.html
в папке app/elements
):
<link rel="import" href="../bower_components/polymer/polymer.html">
<polymer-element name="habrauser-card" attributes="habrauser usercolor">
<template>
<style>
:host {
display: block;
padding: 10px;
color: {{usercolor}};
}
polyfill-next-selector { content: ':host h3'; }
:host ::content h3 {
margin: 0;
text-decoration: underline;
}
</style>
<content select="h3"></content>
<li>I am habrauser <b>{{habrauser}}</b></li>
<li><content></content></li>
</template>
<script>
Polymer('habrauser-card', {
habrauser: 'DefaultValue',
usercolor: 'green'
});
</script>
</polymer-element>
Давайте разберем:
Сначала подключаем polymer.html
или любую другую компоненту, внутри которой уже есть линк на polymer.html
.
Затем в тэге <polymer-element>
определяем наш элемент <habrauser-card>
(Важно! Имя должно быть обязательно со знаком '–'). В свойстве attributes
перечисляем внешние (которые будем использовать при вызове) свойства. Я бы назвал это интерфейсом веб-компоненты. Их еще можно задать через js и свойство publish:
, но способ задания через аргумент предпочтительнее.
Дальше идет шаблон на языке html (то, что заключено в теги <template>
).
Стили можно писать прямо здесь в тэг <style>
, а можно подгружать внешний файл (все как в обычном html). Причем Polymer задержит «регистрацию» элемента до полной загрузки таблицы стилей. :host
— это селектор нашего <habrauser-card>
элемента, т.е. корневой.
В тег <content>
подставиться то, что заключено в наш тег <habrauser-card>
при вызове. Содержимое тега <habrauser-card>
можно даже разобрать по 'внутренним' тегам, и вывести в нужных местах. Для этого используется аргумент select
у тэга <content>
.
Ну и в конце тег <script>
, в котором естественно js, его тоже можно подгрузить в виде файла. Polymer([tag-name,] [prototype])
— это удобная обертка для привязки свойств и методов к элементу.
И конечно дата-байдинг. Просто вставьте «двойные усы» {{param}}
в текст, в атрибуты, в стили, везде и все работает. Если переменная изменится, то поменяется везде и сразу. Причем если это внешняя переменная (интерфейс), то измененное значение можно передать «наверх».
Вот и все компонента описана и теперь можно ее использовать в index.html
:
<!-- добавляем линк на наш элемент -->
<link rel="import" href="elements/habrauser-card.html">
...
<div class="hero-unit">
...
<!-- вызываем наш элемент несколько раз -->
<habrauser-card habrauser='Petya' usercolor='red'>This text from index.html</habrauser-card>
<habrauser-card habrauser='Ivan'><h3>Hello!</h3> The end text!</habrauser-card>
<habrauser-card usercolor='blue'><input placeholder="type here"></habrauser-card>
</div>
После сохранения в браузере Вы увидите такую картинку:
Давайте попробуем немного расширить функционал нашей компоненты: по клику на наше имя вызовем функцию:
...
<li>I am habrauser <b on-click="{{resetColor}}">{{habrauser}}</b></li>
...
Polymer('habrauser-card', {
habrauser: 'DefaultValue',
usercolor: 'green',
resetColor: function() {
this.usercolor = 'green';
}
...
и в index.html
тоже немного подправим, обернув в тэг <template>
наши вызовы (для работы дата-биндинга в нашем index.html
).
<template is="auto-binding">
<habrauser-card habrauser="Petya" usercolor="red">This text from index.html</habrauser-card>
<habrauser-card habrauser="Ivan"><h3>Hello!</h3> The end text!</habrauser-card>
<habrauser-card usercolor="{{newcolor}}"><input placeholder="type here" value="{{newcolor}}"></habrauser-card>
</template>
Результат будет такой:
Ну и последний пример — это массив и repeat
по нему. Замените в index.html
:
<div class="hero-unit">
<yo-greeting></yo-greeting>
<p>You now have</p>
<yo-list></yo-list>
<template id="my-tpl" is="auto-binding" repeat="{{habrausers}}">
<habrauser-card habrauser="{{name}}" usercolor="{{color}}">{{text}}</habrauser-card>
</template>
</div>
<script>
document.querySelector('#my-tpl').habrausers = [
{name: 'Vasya', color: 'red', text: 'It is a good day!'},
{name: 'Petya', color: 'green', text: 'Are you clever?'},
{name: 'Masha', color: 'violet', text: 'I am beautifull!'},
{name: 'Ira', color: 'orange', text: 'It is a future!'}
];
</script>
Результат будет такой
И напоследок, крайне рекомендую посмотреть видео с Google I/O 2014 — Раз и Два
Ну и самая главная ссылка этого поста, куда в случае заинтересованности придется не раз обращаться.
Автор: pofigizm