- Первый опыт
- стилизованный метод: оберните компоненты React в стилизованные компоненты
- ( ) три случая
- tagged template literal
- интерполяции интерполяционные выражения
- mixin
- Связанные свойства StyledComponent
- продлить наследство
- withComponent
- component-selector
- innerRef
- isStyledComponent
- Метод attrit: добавить атрибуты по умолчанию в созданные компоненты
- Компоненты темы
- defaultProps
- Об объектах темы
- ThemeProvider, вложенный в тему Function
- Получить тему в компоненте React
- Метод injectGlobal: вставка глобальных стилей
- метод ключевых кадров: использовать покадровую анимацию
- разное
pre-notify
previously:
В сегодняшнем все более компонентном развитии мы передаемJSX
js и html/xml были смешаны вместе, так что насчет css?
Хотя в такой среде, как vue, мы можем.vue
В файле css, js и html прописаны вместе, но по факту их связь очень слабая, особенно js и css, они совершенно не умеют общаться.
а такжеstyled-components
Он очень хорошо решает эту проблему, с его помощью мы можем заставить всю архитектуру CSS следовать за компонентами, а не просто размещаться в файле. Можно сказать, что styled-components делают компонент более полным и более похожим на компонент!
Первый опыт
styled-compnents
, как следует из названия, выполнен в стилеreact-component
, является перепаковкой компонента реакции, он может не только идти в<Component/>
Добавлены фиксированные стили CSS, и CSS можно тесно связать с компонентом через свойства компонента.
Кроме того, он поддерживает почти всеsass/less
и другие функции, которыми обладают препроцессоры CSS, вложенность,&
, переменные, интерполяция и многое другое!
Давайте сначала посмотрим на основное использование каштанов.
// 把一个React-Component包装成Styled-Component
import React,{Component}from 'react';
import styled from 'styled-components';
class Xxx extends React.Component{
render(){
return (
<div className={this.props.className}>
container
<h2>title</h2>
<div>body</div>
</div>
)
}
}
const StyledComponent = styled(Xxx)`
&{
color:red;
h2{
color:blue;
}
div{
font-size:${props=>props.fontSize};
color:pink;
}
}
`;
export default StyledComponent;
styled()
даstyle-components
Самый важный метод в , он оборачивает компонент React в стилизованный<StyleComponent/>
, а также пройдетclassName
Атрибут, значением этого атрибута является строка хеш-значений (для предотвращения конфликтов имен), нам нужнопоместите его на элемент, где он должен быть размещен.
пройти черезstyled()
, мы обернули компонент React в компонент Styled и экспортировали его, затем давайте отрендерим этот экспортированный компонент
import React from 'react';
import ReactDOM from 'react-dom';
import StyledComponent from './test.js';
ReactDOM.render(
<StyledComponent fontSize='30px'/>
,window.root
)
Результат рендеринга выглядит так:
Можно обнаружить, что нет никакой разницы между используемым StyledComponent и ReactComponent, эммм, следует сказать, что есть еще немного, мы можем передавать атрибуты компоненту для управления стилем CSS компонента, Итак, StyledComponent на самом деле является надмножеством ReactComponent.
Ну что, интересно? Давайте узнаем больше вместеstyle-components
Бар!
стилизованный метод: оберните компоненты React в стилизованные компоненты
Мы уже знаем, что styled может делать в Shangli, на этот раз давайте полностью проанализируем этот API.
Сначала его формат такой
const StyledCompoent = styled()``
Он получает два параметра (на самом деле это способ написания функции метки в es6, который здесь не будет расширяться) и, наконец, возвращает обернутый компонент React, то есть стилизованный компонент React.
( ) три случая
()
может получитьReact-Component
также может получитьtagName
.
В предыдущем каштане мы продемонстрировали первый случай, так что на самом деле он также может получить tagName, такой какdiv
const StyledCompoent = styled('div')``
На самом деле, это эквивалентно
let ReactComponent = (props,context)=><div className={props.className}></div>; //上栗中我们说过当我们调用styed()时,react组件中会自动传入一个由hash组成的className属性
const StyledCompoent = styled(ReactComponent)``
Кроме того, у него есть ярлык
const StyledCompoent = styled.div``
Что ж, в дополнение к двум вышеупомянутым основным ситуациям, есть еще одна ситуация, которая()
также может получить StyledComponent, что чаще всего происходит вКогда стиль StyledComponent должен наследоваться от другого StyledComponent.
const StyledCompoent2 = styled(StyledCompoent1)`
color:'orange'
`
tagged template literal
эммм... как это перевести? Строка шаблона ярлыка? Литералы шаблонов с тегами?
Неважно~ В любом случае, это относится к скобкам (()
)После``содержание в.
проходя черезstyled()
После того, как мы убедились, чтоЭффективныйАктуальный компонент инициализируется для стилизованного компонента, а затем нам нужно только добавить стиль к этому компоненту.
const StyledCompoent = styled.div`
/* all declarations will be prefixed */
//所有css样式会自动添加兼容性前缀
padding: 2em 1em;
background: papayawhip;
/* pseudo selectors work as well */
//支持伪类选择器
&:hover {
background: palevioletred;
}
/* media queries are no problem */
//支持媒体查询
@media (max-width: 600px) {
background: tomato;
/* nested rules work as expected */
//支持嵌套
&:hover {
background: yellow;
}
}
> p {
/* descendant-selectors work as well, but are more of an escape hatch */
//支持后代选择器
text-decoration: underline;
}
/* Contextual selectors work as well */
//支持环境选择器
html.test & {
display: none;
}
`;
Приведенный выше пример из официального документа, видно, что в нем нет поддержки Yali: вложенность,Автодополнение префикса, различные селекторы, медиа-запросы...
интерполяции интерполяционные выражения
Кроме того, конечно, он также поддерживает переменные, и есть два варианта
let color1 = 'orange';
const StyledCompoent = styled.div`
color:${color1} //支持接收js变量作为css属性值
,fontSize:${props=>props.fontSize}; //支持接收组件的props中的某个值来作为css属性值
`
//--- --- ---
// somewhere
...
<StyledComponent fontSize='30px'/>
...
один из них${}
называетсяinterpolations
эм, интерполяционное выражение, его надо назвать?
Следует отметить, что в ${} можно поместить переменную js или функцию. Если это функция, она приметprops
Свойства (то есть объект реквизита, обернутый при инициализации компонента React) используются в качестве параметров.
Эй, есть еще одна возможность, ${} также может получить объект css, например этот
...
${{
position:'absolute'
,left:'100px'
,top:'100px'
}}
...
mixin
styled-components также позволяет нам использовать такие вещи, как @mixin в sass.
import React,{Component}from 'react';
import styled,{css} from 'styled-components';
class Xxx extends React.Component{
render(){
return (
<div className={this.props.className}>
container
<h2 className='title'>title</h2>
<div className='content'>body</div>
</div>
)
}
}
let mixin = css`
&{
color:red;
${{
position:'absolute'
,left:'100px'
,top:'100px'
}}
.title{
color:blue;
}
.content{
font-size:${props=>props.someCondition.fontSize};
color:pink;
}
}
`
const StyledComponent = styled(Xxx)`
${props=>props.someCondition?mixin:null}
`;
export default StyledComponent;
// --- --- ---
ReactDOM.render(
<StyledComponent someCondition={{fontSize:'30px'}}/>
,window.root
)
Среди них мы использовали еще один метод в styled-componentscss
, этот метод фактически создаетmixin
, так что мы можем использовать любой<StyledComponent>
повторно используйте этот стиль.
должны знать о том,props
свойства могутпроникнутьДатьmixin
сделать так, чтобы он использовался внутри (иначе как бы мы сказали, что это миксин)
Окончательный результат рендеринга выглядит так
Связанные свойства StyledComponent
через предыдущий разделstyled()
метод оборачивает компонент реакции в стилизованный компонент реакции, мы называем егоStyledComponent
, помимо того, что он тесно связан с компонентами по стилю, он также обладает некоторыми уникальными особенностями.
продлить наследство
Как мы уже говорили, мы можемstyled(StyledCompoent1)
StyleComponent для создания StyledComponent2, наследуемого от StyledComponent1.
let StyledCompoent2 = styled(StyledCompoent1)`
color:xxx
...
`
Но такое наследование на самом делезаводской узор, StyledComponent2 на самом деле является совершенно новым классом.
если мы хотим сделатьистинное наследство, вам нужно использовать компоненты стиля, предоставленныеextend
метод, который является методом свойства в StyleComponent.
let StyledCompoent2 =StyledCompoent1.extend`
color:xxx
...
`
withComponent
withComponent также является методом свойства в StyleComponent, который может помочь нам заменить метку в исходном компоненте Styled другой меткой.
//会将原本的<button>替换成<a>
const Link = Button.withComponent('a');
[danger] Уведомление:Если исходный компонент Styled является компонентом с составным тегом, то будет заменен весь его DOM, что может оказаться не таким, как вы ожидаете.
component-selector
styled-components позволяет нам использоватьtagged template literal
используйте переменную StyledComponent в качестве селектора CSS, давайте назовем ееcomponent-selector
.
Уведомление:Все еще нужно вручную найти начальную позицию className
let ReactComponent = (props,context)=>{
<div className={props.className}>
<h2>hello</h2>
</div>
}
let StyledComponent1 = styled(ReactComponent)``
let StyledComponent2 = styled.div`
${StyledComponent1}{
background:orange;
h2{
color:red;
}
&:after{
content:'';
display:block;
width:10px;
height:10px;
border:1px solid black;
}
}
`
//--- --- ---
...
ReactDOM.render(
<StyledComponent2>
<StyledComponent1/>
</StyledComponent2>
,window.root
)
innerRef
В styled-components, если мы хотим получить реальную запись DOM StyledComponent, нам нужно использовать innerRef вместо ref (функция и использование одинаковы).
const Input = styled.input`
padding: 0.5em;
margin: 0.5em;
color: palevioletred;
background: papayawhip;
border: none;
border-radius: 3px;
${{color:'red'}}
`;
export default class Form extends React.Component {
render() {
return (
<Input
placeholder="Hover here..."
innerRef={x => { this.input = x }}
onMouseEnter={() => this.input.focus()}
/>
);
}
}
Нажмите, чтобы увидеть официальный пример
Используемый верхний каштанstyled.input
Этот быстрый способ создать styledComponent,
Если мы перейдем к использованиюstyled(原生React组件)
образом, тогда мы не можем получить дом, как указано выше, мы получаемstyled()
Нативный объект компонента React, переданный в круглых скобках
class _B extends React.Component{
render(){
return <div></div>
}
}
const B = styled(_B)``;
export default class A extends React.Component{
componentDidMount(){
console.log('this.dom', this.dom);
}
render(){
return <B innerRef={x => this.dom = x}></B>;
}
}
(То, что вы получаете, это не dom, а объект компонента до того, как он будет стилизован)
Решение находится в_B
использовать роднойref
Смонтируйте один раз, смонтируйте дом в_B
, чтобы мы могли получить дом, перейдя на один уровень ниже.
isStyledComponent
Иногда нам нужно решить, является ли компонент StyledComponent, чтобы мы могли использовать функции, которые есть только у StyledComponent, такие какcomponent-selector
import React from 'react';
import styled, { isStyledComponent } from 'styled-components';
import MaybeStyledComponent from './somewhere-else';
let TargetedComponent =
isStyledComponent(MaybeStyledComponent)
? MaybeStyledComponent
: styled(MaybeStyledComponent)``;
const ParentComponent = styled.div`
color: cornflowerblue;
${TargetedComponent} {
color: tomato;
}
`
Уведомление:Метод isStyledComponent требует дополнительного импорта из styled-components.
Метод attr: добавление атрибутов по умолчанию к компонентам Styled
Метод attr принимает объект, который позволяет нам добавлять атрибуты по умолчанию и значения стиля по умолчанию в StyledComponent.
Этот метод также является одним из наиболее важных методов в styled-components.
const Input = styled.input.attrs({
// 定义一些静态属性
type: 'password',
// 给css属性动态赋予初始值
margin: props => props.size || '1em',
padding: props => props.size || '1em'
})`
color: palevioletred;
font-size: 1em;
border: 2px solid palevioletred;
border-radius: 3px;
/* here we use the dynamically computed props */
margin: ${props => props.margin};
padding: ${props => props.padding};
`;
export default class xxx extends React.Component{
render(){
return (
<div>
<Input placholder='A small text input' size='1em'/>
<br/>
<Input placholder='A bigger text input' size='2em'/>
</div>
)
}
}
Окончательный результат рендеринга выглядит так
Компоненты темы
Предоставлено нам styled-componentsThemeProvider
компонент (да, компонент React), мы можем настроить тему для нашего StyledComponent.
import React from 'react';
import styled,{ThemeProvider} from 'styled-components';
// 定制主题
const theme = {
main:'mediumseagreen'
}
const Button = styled.button`
font-size:1em;
margin:1em;
padding:0.25em 1em;
border-radius:3px;
/*color the border and text with theme.main*/
color:${props=>props.theme.main}; //——》这里使用主题提供的属性
border:2px solid ${props=>props.theme.main};
`
export default class xxx extends React.Component{
render(){
return(
<div>
<Button>Normal</Button>
<ThemeProvider theme={theme}>
<Button>Themed</Button>
</ThemeProvider>
</div>
)
}
}
Нажмите, чтобы увидеть официальный пример
На каштан мы настроилиtheme
предметный объект и передать этот объект<ThemeProvider>
компонент, чтобы в любом дочернем компоненте, обернутом этим компонентом, мы могли получить этоtheme
Объекты (независимо от того, сколько уровней вложенности).
defaultProps
На самом деле в Shangli есть ошибка, то есть это не<ThemeProvider>
завернутый<Button/>
На самом деле нет объекта свойства props.theme, тогда он сообщит об ошибке.
Итак, на данный момент нам нужно установить значение по умолчанию для этого компонента кнопки.
...
// 设置默认属性,
Button.defaultProps = {
theme:{
main:'palevioletred'
}
}
const theme = {
main:'mediumseagreen'
}
...
Об объектах темы
На самом деле, в дополнение к определению объекта темы вне компонента и передаче<ThemeProvider theme={theme}>
Помимо передачи, мы также можем определить объект темы непосредственно в StyledComponent.
...
const theme = {
main: 'mediumseagreen'
};
...
<ThemeProvider theme={theme}>
<div>
<Button>Themed</Button>
<Button theme={{ main: 'darkorange' }}>Overidden</Button>
</div>
</ThemeProvider>
...
ThemeProvider, вложенный в тему Function
когдаThemeProvider
При вложенности свойство темы вложенного ThemeProvider может принимать не только объект, но и функцию, если это функция, то функция получит параметр, который получает предыдущий объект ThemeProvide.theme.
...
const theme = {
fg:'palevioletred'
,bg:'white'
};
const invertTheme = ({fg,bg})=>({
fg:bg
,bg:fg
})
...
<ThemeProvider theme={theme}>
<div>
<ThemeProvider theme={invertTheme}>
<Button>Themed</Button>
</ThemeProvider>
</div>
</ThemeProvider>
...
Нажмите, чтобы увидеть официальный пример
Получить тему в компоненте React
Если вы хотите получить тему в компонентах React, styled-compnents также предоставляет намwithTheme
метод, после его упаковки мы можем получить props.theme в компоненте React
import { withTheme } from 'styled-components'
class MyComponent extends React.Component {
render() {
console.log('Current theme: ', this.props.theme);
// ...
}
}
export default withTheme(MyComponent)
Метод injectGlobal: вставка глобальных стилей
Во-первых, это дополнительный метод, предоставляемый styled-components.
import { injectGlobal } from 'styled-components';
injectGlobal`
@font-face {
font-family: 'Operator Mono';
src: url('../fonts/Operator-Mono.ttf');
}
body {
margin: 0;
}
`;
Что ж, официальная рекомендация заключается в том, что вам лучше использовать его только для шрифта и тела.
метод ключевых кадров: использовать покадровую анимацию
часто иinterpolation
использовать вместе
import styled, { keyframes } from 'styled-components';
const fadeIn = keyframes`
0% {
opacity: 0;
}
100% {
opacity: 1;
}
`;
const FadeInButton = styled.button`
animation: 1s ${fadeIn} ease-out;
`;
Нажмите, чтобы увидеть официальный пример
разное
О рендеринге на стороне сервера
О машинописном языке
О ReactNative
На что следует обратить внимание при использовании стилизованных компонентов в ReactNative
Обновление для styledComponent
Если передается новое состояние и необходимо добавить новый cssText, он перейдет кstyle
Добавьте cssText к тегу,
Обратите внимание, что добавление к нему не удалит предыдущий cssText в стиле. (Даже если текущий реквизит больше не соответствует условиям генерации предыдущего текста CSS, он не будет удален)
Ссылаться на