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

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

Avatar for FrontFest FrontFest
November 21, 2017

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

Avatar for FrontFest

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