Привет, Хабр! На днях наткнулся на одну очень интересную статью на португальском. К счастью, удалось найти её английскую версию. Предлагаю вашему вниманию перевод на русский. Другие мои переводы вы можете найти на мой странице на хабре.

Ссылка на оригинал: португальский, английский

Для тех кто не в теме. Styled-Components это библиотека очень популярная в среде React & Ract-native разработчиков. Она позволяет писать пользовательский CSS прямо в JS.

Во Vue мы знаем сколь удобно работать с однофайловыми компонентами(SFC), ведь всё необходимое компоненту собрано в одном месте. Паттерн SFC существенно повысил популярность Vue.

Крайние несколько месяцев мне довелось принять участие в разработке крупного проекта на React. В нём мы использовали Styled-Components, и это был очень интересный опыт.

Однако, в большинстве своих проектов я использую Vue, поэтому естественно, что мне захотелось объединить новый опыт со Styled-Components и преимущества Vue.js экосистемы. Именно тогда я обнаружил, что такое решение уже есть и оно поддерживается теми же создателями, что и аналогичная библиотека под React: vue-styled-components.

Начало


Отложим пустую болтовню и перейдём к коду. Как обычно, используйте yarn или npm.

// for yarn
yarn add vue-styled-components
// for npm
npm install --save vue-styled-components 


На моём гитхабе вы найдёте репозиторий с примерами использования этой библиотеки.

Каждый элемент, используемый в примерах, может обрабатываться vue-styled-компонентами как изолированный компонент с его индивидуальными свойствами или путем получения данных от других компонентов.

Наш первый пример просто кнопка с дефолтными стилями.

import styled from "vue-styled-components";

const CButton = styled.button`
  font-size: 1em;
  text-align: center;
  color: #FFFFFF;
  border-radius: 5px;
  padding: 10px 15px;
  background-color: #0057AA;
`;

export default CButton;


В любом месте нашего приложения мы можем использовать этот компонент.

    import CButton from '@/components/elements/Button'
    export default {
        name: 'app',
        components: {
            CButton
        },
    }


Передача параметров


В vue-styled-components вы можете динамически определять стили для компонента, передавая эти значения через свойства. Этот пример иллюстрирует, что при передаче основного атрибута кнопка получит новый стиль фона и цвет шрифта.

import styled from "vue-styled-components";

const typeButton = { primary: Boolean };

const CButtonProps = styled('button', typeButton)`
  font-size: 1em;
  text-align: center;
  color: ${props => props.primary ? '#0057AA' : '#FFFFFF'};
  border-radius: 5px;
  padding: 10px 15px;
  background-color: ${props => props.primary ? '#FFFFFF' : '#0057AA'};
`;

export default CButtonProps;


Приведенный выше пример может быть улучшен и даже добавлены новые свойства (вы можете передать столько атрибутов, сколько захотите). Все идет в соответствии с вашими потребностями в рамках проекта.

С помощью этой библиотеки мы получаем возможность управлять стилями через логику. В приведенном ниже примере у вас есть возможность выбрать, какую цветовую схему вы хотите назначить своей кнопке, не влияя на другие, тем самым разнообразив ваше приложение.

import styled from "vue-styled-components";

const typeButton = {
    type: String,
    radius: Boolean
};

const styleButton = type => {
    switch (type) {
        case "primary":
            return `
                background-color: #FFFFFF;
                color: #0057AA;
            `;
        case "error":
            return `
                background-color: #B4000B;
                color: #FDFDFD;
            `;
        case "success":
            return `
            background-color: #00C887;
            color: #37435F;
        `;
        default:
            return `
                background-color: #0057AA;
                color: #FFFFFF;
            `;
    }
}

const CButtonPropsCond = styled('button', typeButton)`
  font-size: 1em;
  text-align: center;
  padding: 10px 15px;
  border-radius: ${({ radius }) => radius ? "6px" : null};
  ${(props) => styleButton(props.type)}
`;

export default CButtonPropsCond;


Чтобы лучше объяснить процесс создания этой кнопки: мы сначала (всегда) импортируем vue-styled-components, сразу после (от строки 3 до строки 6) нам нужно определить, какие типы свойств будут переданы компоненту. От строки 8 до 31 мы создаем функцию, которая принимает значение свойства type, в соответствии с тем, что было передано, оно возвращает атрибуты фона. цвет и цвет их соответствующего регистра, если в качестве свойства ничего не передано, то кнопке будет присвоено значение по умолчанию.

Благодаря этим знаниям вы можете реализовать новые атрибуты, которые сделают ваш пользовательский компонент очень динамичным.

Я оставил эти маленькие примеры в своем GitHub, чтобы вы могли сделать начальный шаг в освоении этой библиотеки. Наслаждайтесь.

Ссылка на репозиторий с примерами.

Комментарии (10)


  1. Focushift
    19.09.2019 18:08

    Непонятно только зачем это нужно? Усложнить проект, замедлить сборку?
    Чем оно лучше чем готовые стили в CSS? Или просто чтобы было как в реакте?
    данная библиотека добавляет возможность создания элементов «нестандартным» способом, что усложняет понимание исходников.


    1. Alex_Shcherbackov Автор
      20.09.2019 08:32

      Вы можете сделать компоненты на ес6 классах и стилизованных-компонентах, так они будут менее зависимы от Vue. В случае необходимости вы сможете даже перейти на другой фреймворк. Так сделано в Едадиле, например.


    1. Alex_Shcherbackov Автор
      20.09.2019 08:35

      Я не пропагандирую данный подход, но для расширения кругозора, на мой взгляд, полезно знать альтернативы.


  1. radist2s
    20.09.2019 07:23

    Лично я предпочитаю использовать CSS модули, так же с импортом стилей в основном коде компонента, Webpack же делает всю остальную магию. Так же можно сразу же для стилей (css, sass, less) с помощью tsm сгенерировать d.ts файл, в котором будет список всех классов и других экспортированных переменных. Это удобно, так как если что-то из стилей удалить, но не обновить при этом код компонента, то проект просто не будет собираться. И ситуации, когда класс есть, а стилей для него нет просто невозможны в принципе.
    А Styled Components у меня так и не прижились, нормальная подсветка синтаксиса все же пока что важнее.


    1. Alex_Shcherbackov Автор
      20.09.2019 08:34

      Я отношусь к статья примерно так: надо ознакомится и иметь в виду. Кругозор — штука важная.


  1. Feaman
    20.09.2019 08:32

    Ужас какой-то. Вместо отличного и всем понятного css придумали этого монстра. Чем больше узнаю о react тем больше люблю vue. Иногда складывается ощущение, что в react почти ничего нельзя сделать и для решения этих проблем созданы сотни библиотек. Просто пользуйтесь vue. :-)


    1. Focushift
      20.09.2019 13:13

      И эта либа еще не такая как все, и ни с чем не совместима. К примеру веб компоненты.


  1. starsky-mik
    21.09.2019 08:30

    Так вся прелесть SFC именно в том что там уже подразумевается блок style, для которого доступен атрибут scoped.


    Что позволяет разделить css на 3 уровня.
    1) Глобальный, который можно проимпортить во все приложение.
    2) Статичный css компонента, то что находится в блоке style
    3) Динамичный, который можно доопределить через атрибут :style в шаблоне компонента с помощью computed свойства.


    1. Alex_Shcherbackov Автор
      21.09.2019 08:32

      Это безусловно так, я не призываю отказываться от SFC. На мой взгляд, всегда полезно иметь несколько альтернатив любой концепции. Поэтому мне статья нашего португальского коллеги была полезна. Я перевёл её для вас, может ещё кому пригодится.


  1. zogxray
    21.09.2019 09:37

    Имею удовольствие писать и Vue и на React. Скажу прямо — не надо тащить в Vue мрачные ужасы из React. Пусть страх и ненависть будет только в одном случае.