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
Два слова, плагин.
- styled-jsx-plugin-sass
- styled-jsx-plugin-postcss
- styled-jsx-plugin-stylelint
- styled-jsx-plugin-less
- styled-jsx-plugin-stylus
Все есть. Возьмите 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 мелких недостатка
- При интеграции с CRA решение css-in-js не будет загружаться в горячем режиме, а страница будет каждый раз обновляться.
- При интеграции с CRA, поскольку это подключаемый модуль babel, вам необходимо извлечь или использовать
react-app-rewired
чтобы добавить настройки плагина babel.
Некоторые друзья оставили сообщение, прежде чем сказать, что есть яма (спасибо, увидев такое сообщение, я думаю, что решение написать блог слишком правильное)
同样觉得styled-jsx非常好,最近一直在用。
但目前还是有些不成熟的地方,主要是:
1、局部样式无法支持第三方组件标签,只能支持普通html标签
2、对stylelint缺乏支持,官方出的stylelint插件只是一个demo。在vscode中用stylelint插件时也是有很大的坑。
Лично я думаю, что сценарий 1 обсуждался выше и совместим. 2, у меня в последнем проекте есть голый красавчик, поэтому я не пробовал этот плагин, поэтому упомяну его здесь.
В общем, я использовал его один раз, и он мне очень нравится. Надеюсь, вы все найдете одно или несколько решений, которые вам нравятся.
Во время недавнего интервью я понял, что у меня много тем, на которых нужно сосредоточиться. После просмотра некоторых статей и видеороликов, связанных с PWA, я уже сел на корабль. Вывод: PWA — это будущее, и будущее не за горами. Я планирую поделиться своими заметками об исследовании позже.
Список других столбцов, которые я написалпортал.