Пишем компонент с «материальными» кнопками для Svelte

от автора

Вдохновившись статьями SvelteJS: Релиз второй версии, Исчезающие фреймворки и Re: «Сравнение JS-фреймворков: React, Vue и Hyperapp», про «исчезающий» фреймворк Svelte (читается «свелт», а то мало ли), я захотел его попробовать. И для начала решил написать небольшой компонентик с кнопками из Materialize.

Способ первый: классический

Стартовый шаблон Svelte предлагается в двух вариантах: с Webpack или с Rollup. Я использовал Webpack, поскольку он мне привычнее. Установка, запуск — все как обычно.

Устанавливаем 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 и демка.

Способ второй: REPL — попроще и побыстрее

На сайте фреймворка есть крутая «песочница» — REPL, в которой уже есть несколько десятков примеров. А еще там можно форкнуть готовый код, дописать/написать что-то своё и поделиться.
Например, вышеописанный компонент там выглядит так.


ссылка на оригинал статьи https://habr.com/post/418679/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *