React Supplements: мои фавориты из 10 популярных CSS-решений (часть 2)

внешний интерфейс React.js CSS

If you are not paying for the product, you are the product.
Когда товар «бесплатный», вы часто являетесь товаром.

Наконец-то есть время успокоиться и кое-что узнать, и заполнить последнюю статью из этой серии.СерединаПредставляя тахионы, эта статья представляет мой личный фаворит, ни один из них: styled-jsx.

критерий отбора

Прежде чем планировать использовать новый CSS-фреймворк, вам нужно хорошо подумать, будет ли он успешно выполнять задачу во всех ваших сценариях использования.Я резюмировал несколько моментов:

  • Решает ли это болевые точки разработки React: локальный CSS, динамический CSS?
  • Поддерживаются ли все варианты использования css или даже sass? Псевдоклассы, вложенность, анимация, медиазапросы?
  • Совместим ли он со сторонними библиотеками пользовательского интерфейса, которые вам нужно использовать?
  • Может ли он сосуществовать с чистым CSS или другими CSS-фреймворками, чтобы был план Б на случай особых обстоятельств?
  • представление? размер?

styled-jsx

серию продуктов zeit от now to next.js, я поклонник мозга. Простой и удобный в использовании - мое впечатление от проекта zeit. А набор библиотек автономный, styled-jsx и next.js прекрасно совместимы.

1. Основное использование

Первое впечатление от styled-jsx — это vue-решение React css.
yarn add styled-jsxПосле установки неimport, но плагин Babel,.babelrcКонфигурация:

{
  "plugins": [
    "styled-jsx/babel"
  ]
}

Затем используйте его напрямую


render () {
    return <div className='table'>
        <div className='row'>
            <div className='cell'>A0</div>
            <div className='cell'>B0</div>
        </div>
        <style jsx>{`
          .table {
            margin: 10px;
          }
          .row {
            border: 1px solid black;
          }
          .cell {
            color: red;
          }
    `}</style>
    </div>;
}
  • <style>Положение компонента можно настроить как угодно, а стиль всегда применяется ко всем элементам компонента
  • Стили применяются только к этому компоненту и не влияют ни на глобальные, ни на подкомпоненты.
  • Метод реализации примерно состоит в том, чтобы автоматически добавлять уникальную метку ко всем тегам в компоненте.classNameНапример
const App = () => (
  <div>
    <p>只有这个p会被上样式</p>
    <style jsx>{`
      p {
        color: red;
      }
    `}</style>
  </div>
)

будет преобразован в

import _JSXStyle from 'styled-jsx/style'

const App = () => (
  <div className='jsx-123'>
    <p className='jsx-123'>只有这个p会被上样式</p>
    <_JSXStyle styleId='123' css={`p.jsx-123 {color: red;}`} />
  </div>
)

От реализации до принципа, он очень похож на Vue? Если вам не нравится писать стили в рендере, styled-jsx предоставляетcssвспомогательная функция:

import css from 'styled-jsx/css'

export default () => (
  <div>
    <button>styled-jsx</button>
    <style jsx>{button}</style>
  </div>
)

const button = css`button { color: hotpink; }`

Очень идеальное решение css. Давайте посмотрим на styled-jsx для каждого аспекта, упомянутого в «Критериях выбора».

2. Динамический CSS

Динамический css — это легкий ветерок, как и решения для строк шаблонов, таких как стилизованные компоненты, движение и т. д.

export default (props) => (
  <div>
    <button>styled-jsx</button>
    <style jsx>{
      `button { color: ${props.color}; }`
    }</style>
  </div>
)

Вы можете писать неограниченное количество номеров в одном компоненте<style>теги, лучше всего поместить статический css в один тег, динамический в другой, только динамический пересчет и рендеринг каждый раз при рендеринге

const Button = (props) => (
  <button>
     { props.children }
     <style jsx>{`
        button {
          color: #999;
          display: inline-block;
          font-size: 2em;
        }
     `}</style>
     <style jsx>{`
        button {
          padding: ${ 'large' in props ? '50' : '20' }px;
          background: ${props.theme.background};
        }
     `}</style>
  </button>
)

Два замечания:

  • Только стиль, написанный в функции рендеринга, является динамическим, поэтому динамический css не может быть извлечен, как во втором примере.
  • Стиль свойств стиля оригинального обходного пути переопределяет стиль styled-jsx.

3. Как использовать Sass

Два слова, плагин.

Все есть. Возьмите Sass в качестве примера:

yarn add -D node-sass styled-jsx-plugin-sass

.babelrcнастроить

{
  "plugins": [
    [
      "styled-jsx/babel",
      { "plugins": ["styled-jsx-plugin-sass"] }
    ]
  ]
}

Sass готов к использованию.

4. Глобальный CSS

поскольку Vue начинается сscopedключевое слово, styled-jsx начинается сglobalкак ключевое слово.

export default () => (
  <div>
    <style jsx global>{`
      body {
        background: red
      }
    `}</style>
  </div>
)

Глобальный стиль может быть отмечен глобальным.

В редких случаях (например, при передаче глобального класса сторонней библиотеке) вам необходимо сделать один селектор глобальным с синтаксисом, аналогичным css-module.

div :global(.react-select) {
    color: red
}

5. Имятняя поддержка UI Библиотека

Это относительно громоздко.Идея состоит в том, чтобы получить преобразованное имя класса styled-jsx и внедрить его в реквизиты className трехсторонней библиотеки, что не только решает проблему поддержки, но и сохраняет локальный CSS.Код выглядит следующим образом

import Link from 'react-router-dom' // 例子,给Link组件添加样式

const scoped = resolveScopedStyles(
  <scope>
    <style jsx>{'.link { color: green }'}</style>
  </scope>
)

const App = ({ children }) => (
  <div>
    {children}
    <Link to="/about" className={`link ${scoped.className}`}>
      About
    </Link>
    
    {scoped.styles}
  </div>
);

function resolveScopedStyles(scope) {
  return {
    className: scope.props.className, //就是被styled-jsx添加的独特className
    styles: scope.props.children      //就是style,注入到App组件中
  }
}

Конечно, если вы не возражаете против частичного не частичного, вы можете использовать вышеупомянутый:global()грамматика

// 比如Form组件有类名form-item
export default () => (
  <div>
    <Form />
    <style jsx>{`
      div > :global(.form-item) {
        color: red
      }
    `}</style>
  </div>
)

6. Подсветка и завершение синтаксиса

Я использую VSCode:

См. другие ридми на github.

7. Размер? представление?

  • Доступен весь синтаксис CSS
  • Размер gzip 3kb
  • Префикс браузера добавляется автоматически
  • С поддержкой исходной карты, легко отлаживать
  • По словам автора производительность тоже очень высокая

8. style-jsx vs styled-components

Спасибо ziven27 за предложение, попробую рассказать о разнице с самой популярной библиотекой styled-components. (Для обсуждения «первый» относится к style-jsx, а «последний» относится к компонентам стиля)

  • Самая большая разница заключается в том, что первый стиль применяется ко всему компоненту, а второй — только к обернутому элементу. Например, это как разница между vue и inline css. Но на самом деле, пока вы используете sass&Вложенные, последние также могут обернуть самый внешний элемент компонента, а затем написать все стили других элементов. Хотя это не похоже на первоначальный замысел последнего.
  • последнее и обеспечитьclassNameПрекрасно интегрирована трехсторонняя библиотека реквизита (гораздо проще прежней):
const RedButton = styled(Button)`background: red;`

но не обеспечиваетclassNameТрехсторонняя библиотека реквизита беспомощна (конечно, такой ситуации не бывает).

  • Поскольку последний использует режим HOC, он должен иметь дело с проблемой ref, как и все другие HOC (ref обертывающего слоя отличается от ref исходного элемента), и это еще одна вещь.
  • Лично я думаю, что правила первого кратки и ясны (как писать css), последний имеет много «магических» частей (таких как реквизит, тема), а также вводит множество продвинутых способов использования, таких как.extendsнаследование стилей и.attrsИнкапсулирует публичные реквизиты.

Вот тема, это "волшебство" или просто? Например, такие как тема:

// styled-components 使用Provider提供主题,主题可以是样式,也可以是函数
const Button = styled.button`
  color: ${props => props.theme.fg};
  border: 2px solid ${props => props.theme.fg};
  background: ${props => props.theme.bg};

  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border-radius: 3px;
`;

// 主题的样式
const theme = {
  fg: 'palevioletred',
  bg: 'white'
};

// 换前景色和背景色的函数
const invertTheme = ({ fg, bg }) => ({
  fg: bg,
  bg: fg
});

render(
  <ThemeProvider theme={theme}>
    <div>
      <Button>Default Theme</Button>

      <ThemeProvider theme={invertTheme}>
        <Button>Inverted Theme</Button>
      </ThemeProvider>
    </div>
  </ThemeProvider>
);

Существует даже HOC для использования темы вне стилевых компонентов.

import { withTheme } from 'styled-components'

Сильный или нет? Напротив, styled-jsx не имеет API, связанного с темой, а просто полагается на реквизиты для передачи темы:

// styled-jsx
import { colors, spacing } from '../theme'
import { invertColor } from '../theme/utils'

const Button = ({ children }) => (
  <button>
     { children }
     <style jsx>{`
        button {
          padding: ${ spacing.medium };
          background: ${ colors.primary };
          color: ${ invertColor(colors.primary) };
        }
     `}</style>
  </button>
)

Этот вопрос зависит от сценария применения и личных предпочтений.Я принадлежу к группе, которая не любит слишком много "магии" и любит простой API (даже если кода больше). Если у вас есть какие-либо идеи и исправления, пожалуйста, оставьте сообщение.

наконец

Есть 2 мелких недостатка

  1. При интеграции с CRA решение css-in-js не будет загружаться в горячем режиме, а страница будет каждый раз обновляться.
  2. При интеграции с CRA, поскольку это подключаемый модуль babel, вам необходимо извлечь или использоватьreact-app-rewiredчтобы добавить настройки плагина babel.

Некоторые друзья оставили сообщение, прежде чем сказать, что есть яма (спасибо, увидев такое сообщение, я думаю, что решение написать блог слишком правильное)

同样觉得styled-jsx非常好,最近一直在用。
但目前还是有些不成熟的地方,主要是:
1、局部样式无法支持第三方组件标签,只能支持普通html标签
2、对stylelint缺乏支持,官方出的stylelint插件只是一个demo。在vscode中用stylelint插件时也是有很大的坑。

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

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

Во время недавнего интервью я понял, что у меня много тем, на которых нужно сосредоточиться. После просмотра некоторых статей и видеороликов, связанных с PWA, я уже сел на корабль. Вывод: PWA — это будущее, и будущее не за горами. Я планирую поделиться своими заметками об исследовании позже.

Список других столбцов, которые я написалпортал.