Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Владимир Гриненко

FrontFest
November 21, 2017

Владимир Гриненко

FrontFest

November 21, 2017
Tweet

More Decks by FrontFest

Other Decks in Programming

Transcript

  1. Декларативное программирование — это парадигма программирования, в которой задается спецификация

    решения задачи, то есть описывается, что представляет собой проблема и
  2. 4

  3. document .querySelectorAll('.link') .forEach(link => link.style.color = 'red'); document.body.innerHTML += '<a

    class="link" href="http://2017.frontfest.ru">FrontFest</a>'; Императивно 9
  4. document .querySelectorAll('.link') .forEach(link => link.style.color = 'red'); document.body.innerHTML += '<a

    class="link" href="http://2017.frontfest.ru">FrontFest</a>'; Императивно 10 document.querySelector('.link').classList.remove('link');
  5. 20

  6. <div class="dropdown"> <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-

    haspopup="true" aria-expanded="false"> Dropdown button </button> <div class="dropdown-menu" aria-labelledby="dropdownMenuButton"> <a class="dropdown-item" href="#">Action</a> <a class="dropdown-item" href="#">Another action</a> <a class="dropdown-item" href="#">Something else here</a> </div> </div> Шаблонизация 21
  7. <div class="dropdown"> <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-

    haspopup="true" aria-expanded="false"> <?php echo $buttonText; ?> </button> <div class="dropdown-menu" aria-labelledby="dropdownMenuButton"> <?php for ($i = 1; $i <= count($items); $i++) { ?> <a class="dropdown-item" href="<?php echo $items[$i] ["href"]; ?>"><?php echo $items[$i]["text"]; ?></a> <?php } ?> </div> </div> Шаблонизация 22
  8. <div class="dropdown"> <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-

    haspopup="true" aria-expanded="false"> <?php echo $buttonText; ?> </button> <div class="dropdown-menu" aria-labelledby="dropdownMenuButton"> <?php for ($i = 1; $i <= count($items); $i++) { ?> <a class="dropdown-item" href="<?php echo $items[$i] ["href"]; ?>"><?php echo $items[$i]["text"]; ?></a> <?php } ?> </div> </div> Шаблонизация 23
  9. 32

  10. block('user').content()(node => node.ctx.username); block('user') .match()(node => node.ctx.hasIcon) .content()(node => [

    { block: 'icon' }, applyNext() ]); Полная декларативность 42
  11. block('user').content()(node => node.ctx.username); block('user') .match()(node => node.ctx.hasIcon) .content()(node => [

    { block: 'icon' }, applyNext() ]); Полная декларативность 43
  12. block('user').content()(node => node.ctx.username); block('user') .match()(node => node.ctx.hasIcon) .content()(node => [

    { block: 'icon' }, applyNext() ]); Полная декларативность 44
  13. block('data')( tag()('table'), content()(() => ({ tag: 'tr', content: applyNext() })),

    elem('item').tag()('td') ); Полная декларативность: теги 46
  14. <div class="dropdown"> <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-

    haspopup="true" aria-expanded="false"> Dropdown button </button> <div class="dropdown-menu" aria-labelledby="dropdownMenuButton"> <a class="dropdown-item" href="#">Action</a> <a class="dropdown-item" href="#">Another action</a> <a class="dropdown-item" href="#">Something else here</a> </div> </div> Полная декларативность: реальный пример 47
  15. <div class="dropdown"> <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-

    haspopup="true" aria-expanded="false"> <?php echo $buttonText; ?> </button> <div class="dropdown-menu" aria-labelledby="dropdownMenuButton"> <?php for ($i = 1; $i <= count($items); $i++) { ?> <a class="dropdown-item" href="<?php echo $items[$i] ["href"]; ?>"><?php echo $items[$i]["text"]; ?></a> <?php } ?> </div> </div> Полная декларативность: реальный пример 48
  16. <div class="dropdown"> <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-

    haspopup="true" aria-expanded="false"> <?php echo $buttonText; ?> </button> <div class="dropdown-menu" aria-labelledby="dropdownMenuButton"> <?php for ($i = 1; $i <= count($items); $i++) { ?> <a class="dropdown-item" href="<?php echo $items[$i] ["href"]; ?>"><?php echo $items[$i]["text"]; ?></a> <?php } ?> </div> </div> Полная декларативность: реальный пример 49
  17. block('dropdown')( content()(node => [ { block: 'btn', mods: { secondary:

    true }, mix: 'dropdown-toggle', attrs: { type: 'button', id: 'dropdownMenuButton', 'data-toggle': 'dropdown', 'aria-haspopup': true, 'aria-expanded': false } }, { elem: 'menu', attrs: { 'aria-labelledby': 'dropdownMenuButton' }, content: applyNext().map(item => ({ elem: 'item', url: item.url, content: item.text })) } ]), Полная декларативность: реальный пример 50 elem('item').replace()(node => ({ block: 'link', mix: node.ctx, url: node.ctx.url, content: node.ctx.content })) )
  18. { block: 'dropdown', content: [ { elem: 'item', url: 'http://site1.com',

    text: 'Site1' }, { elem: 'item', url: 'http://site2.com', text: 'Site2' }, { elem: 'item', url: 'http://site3.com', text: 'Site3' } ] } Полная декларативность: реальный пример 51
  19. const css = require('./css.json'), visited = {}; block('*') .match()(node =>

    !visited[node.block]) .replace()(node => { visited[node.block] = true; return [ css[node.block], this.ctx ]; }); Полная декларативность: любой узел 52
  20. Что это 59 〉Обертка над стандартными React-компонентами 〉Полностью совместимая со

    стандартными компонентами 〉Не требует знания БЭМ 〉Не требует использования модификаторов 〉Не требует использования уровней переопределения
  21. Что это 60 〉Автоматизирует генерацию классов 〉Позволяет использовать элементы, модификаторы

    и миксы 〉Позволяет использовать уровни переопределения 〉Оперирует компонентами, а не путями
  22. export default class User extends Component { render() { return

    ( <div className="user">{this.props.username}</div> ); } } Было 63
  23. export default decl({ block: 'User', willMount() {}, didMount() {}, willReceiveProps()

    {}, shouldUpdate() {}, willUpdate() {}, didUpdate() {}, willUnmount() {} }); Livecycle-методы 65
  24. Какие проблемы 71 〉Модификации бывают опциональными 〉Композитные модификации › пересечение

    всех вариантов не выражается через наследование › Button, Button_compound, Button_with-icon
  25. import { BaseComponent, warn } from '../../Utilities'; import { ButtonType,

    IButtonProps } from './Button.Props'; import { DefaultButton } from './DefaultButton/DefaultButton'; import { CommandButton } from './CommandButton/CommandButton'; import { CompoundButton } from './CompoundButton/CompoundButton'; import { IconButton } from './IconButton/IconButton'; import { PrimaryButton } from './PrimaryButton/PrimaryButton'; Например, кнопка 72 github.com/OfficeDev/office-ui-fabric-react
  26. public render() { const props = this.props; switch (props.buttonType) {

    case ButtonType.command: return <CommandButton { ...props } />; case ButtonType.compound: return <CompoundButton { ...props } />; case ButtonType.icon: return <IconButton { ...props } />; case ButtonType.primary: return <PrimaryButton { ...props } />; default: return <DefaultButton { ...props } />; } } Например, кнопка 73
  27. // Button_type_compound.js import {declMod} from 'bem-react-core'; import React from 'react';

    export default declMod(({ type }) => type === 'button', { block: 'Button', mods({ type }) { return { ...this.__base.apply(this, arguments), type }; }, content() { return <Button … /> } }); Модификатор 75
  28. library/components/link.css .link { color: red } Как это работает 88

    project/components/link.css .link { text-decoration: none }
  29. // blocks/Link/Link.js import decl from 'bem-react-core'; export default decl({ block:

    'Link', tag: 'a', attrs(({url}) => ({href: url})) }); <Link url="…">… <a class="Link" href="…">… Уровни переопределения 91
  30. // blocks/Link/Link.js // a11y/blocks/Link/Link.js import decl from 'bem-react-core'; export default

    decl({ block: 'Link', attrs() { return { ...this.__base.apply(this, arguments), role: 'link' }; } } <Link url="…">… <a class="Link" href="…" role="link">… Уровни переопределения 92