- PVSM.RU - https://www.pvsm.ru -
Вдохновившись статьями SvelteJS: Релиз второй версии [1], Исчезающие фреймворки [2] и Re: «Сравнение JS-фреймворков: React, Vue и Hyperapp» [3], про «исчезающий» фреймворк Svelte (читается «свелт», а то мало ли [4]), я захотел его попробовать. И для начала решил написать небольшой компонентик с кнопками из Materialize [5].
Стартовый шаблон Svelte предлагается в двух вариантах: с Webpack или с Rollup. Я использовал Webpack, поскольку он мне привычнее. Установка, запуск — все как обычно [6].
Устанавливаем Materialize и иконочки:
npm install materialize-css@next
npm install material-design-icons
В подключаем все это в src/main.js:
import 'material-design-icons/iconfont/material-icons.css';
import 'materialize-css/dist/css/materialize.min.css';
Установим file-loader, чтобы обрабатывать шрифты (и не только):
npm install file-loader --save-dev
И добавим настройки в webpack.config.js:
{
test: /.(woff(2)?|ttf|eot|svg)(?v=d+.d+.d+)?$/,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}]
}
Создаем файл src/components/Buttons.html — собственно, это и будет компонент. В Materialize для кнопок почему-то используется тег <a>, поэтому, для семантичности, было решено сделать два вида кнопок: <button> — если ссылки нет, и <a> — если ссылка есть.
Пишем два шаблона:
{#if href} // Проверка на наличие ссылки
<a on:click class="{classes}" {href} {title} >
{#if icon} // И на наличие иконки
<i class="material-icons {iconAlign}">{icon}</i>
{/if}
<slot>button</slot>
</a>
{:else}
<button on:click class="{classes}" {type} {name} {disabled} >
{#if icon}
<i class="material-icons {iconAlign}">{icon}</i>
{/if}
<slot>button</slot>
</button>
{/if}
Здесь {classes} — список классов, {href}, {title}, {type}, {name}, {disabled} — соответствующие атрибуты, а {iconAlign} и {icon} — позиция и название иконки. Атрибуты можно добавить и другие (там, в основном, экзотика осталась), но для примера этого должно быть достаточно.
А on:click добавим, чтобы потом клики по кнопочкам ловить. Пример будет ниже.
Дальше, в секции <script> описываем данные по-умолчанию и добавление классов (computed):
export default {
data() {
return {
color: '',
size: '',
iconAlign: 'left',
floating: false,
flat: false,
waves: false,
wavesColor: 'light',
icon: '', // название иконки
type: '',// и нужные атрибуты
href: '',
name: '',
disabled: false,
title: ''
};
},
computed: { // здесь описываем добавление классов
classes: ({ // перечисляем свойства, которые используем при вызове кнопки
color,
size,
floating,
flat,
disabled,
waves,
wavesColor
}) => {
const classes = [];
flat ? classes.push(`btn-flat`) : classes.push(`btn`);
floating && classes.push(`btn-floating`);
disabled && classes.push(`disabled`);
waves && classes.push(`waves-effect`);
wavesColor && classes.push(`waves-${wavesColor}`);
size && classes.push(`btn-${size}`);
color && classes.push(`${color}`);
return classes.join(' ');
}
}
};
В разделе data() описываем данные по-умолчанию, а в computed — заполняется массив классов на основе свойств, которые мы будем передавать при вызове кнопки. Причем при изменении этих свойств все автоматически пересчитается. Р — реактивность.
Собственно, компонент готов. В src/App.html подключаем его:
<script>
import Button from './components/Buttons.html';
export default {
components: {
Button
}
};
</script>
<Button waves></Button>
<Button waves icon="cloud" iconAlign="left"></Button>
<Button floating waves size="large" color="red" icon="add"></Button>
Или ссылки:
<Button href="#foo" waves> Link_0 </Button>
<Button href="#bar" waves icon="cloud"> Link_1 </Button>
<Button href="#qux" waves flat> Link_2 </Button>
<Button href="#baz" waves icon="cloud" iconAlign="right"> Link_3 </Button>
<Button href="#foo" waves floating size="large" color="red" icon="add" />
С помощью on:click можно ловить клики по кнопке, например так:
<Button on:click="set({ count: count + 1 })" waves>Button++</Button>
<Button on:click="set({ count: count - 1 })" waves icon="cloud" iconAlign="left">Button--</Button>
Для этого в нужно добавить код в export default:
data() {
return {
count: 3
};
},
И где-нибудь этот счетчик вывести:
<p>Count: {count}</p>
Код на GitHub [7] и демка [8].
На сайте фреймворка есть крутая «песочница» — REPL, в которой уже есть несколько десятков примеров. А еще там можно форкнуть готовый код, дописать/написать что-то своё и поделиться.
Например, вышеописанный компонент там выглядит так [9].
Автор: Xtray
Источник [10]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/287686
Ссылки в тексте:
[1] SvelteJS: Релиз второй версии: https://habr.com/post/353896/
[2] Исчезающие фреймворки: https://habr.com/post/414869/
[3] Re: «Сравнение JS-фреймворков: React, Vue и Hyperapp»: https://habr.com/post/417747/
[4] а то мало ли: https://habr.com/post/417747/#comment_18908103
[5] кнопками из Materialize: https://materializecss.com/buttons.html
[6] все как обычно: https://svelte.technology/guide#getting-started
[7] GitHub: https://github.com/kubasovp/svelte-materialize
[8] демка: https://kubasovp.github.io/
[9] выглядит так: https://svelte.technology/repl?version=2.9.7&gist=7abb2ade3ec2358680492f4d444dd047
[10] Источник: https://habr.com/post/418679/?utm_campaign=418679
Нажмите здесь для печати.