avant-propos
Continuer l'article précédent # Construire une bibliothèque d'interface utilisateur frontale basée sur React (3) - composants de base Icon et Button . Nous continuons à ajouter des composants, cette fois en enregistrant les composants de mise en page Box et Combine.
Le code de cet article montre le code principal du schéma de base. Consultez le référentiel pour tous les codes : Gitee repository
Boîte
En ce qui concerne la mise en page, la plus populaire est la mise en page flex, et le composant Box est une encapsulation de la mise en page flex. Sans plus tarder, passons au code. src/component
Créez un nouveau dossier sous le dossier et Box
créez un nouveau fichier dedans index.tsx
:
export interface BoxProps {
children?: ReactNode;
direction?: 'row' | 'row-reverse' | 'column' | 'column-reverse';
wrap?: 'nowrap' | 'wrap' | 'wrap-reverse';
alignItems?: 'center' | 'flex-start' | 'flex-end' | 'stretch';
alignContent?: 'center' | 'flex-start' | 'flex-end' | 'space-between' | 'space-around';
justifyContent?:
| 'center'
| 'flex-start'
| 'flex-end'
| 'space-between'
| 'space-around'
| 'stretch';
padding?: number | string;
width?: string;
height?: string;
flex?: string;
}
class Box extends PureComponent<BoxProps> {
render() {
const box = <BoxWrap {...this.props} />;
return box;
}
}
...
复制代码
Ce qui précède définit certains paramètres de réception, qui correspondent aux paramètres CSS de flex.Nous pouvons compléter le composant en implémentant chaque paramètre spécifique dans le code. Implémentez ensuite le BoxWrap
composant :
import styled from '@emotion/styled';
import { css } from '@emotion/core';
export const BoxWrap = styleWrap({
className: prefixCls,
})(
styled('div')((props: any) => {
// 要实现的内容
}),
);
复制代码
L'étagère a été configurée, à l'ancienne, utilisez toujours styleWrap pour envelopper une couche de styles publics, et utilisez une div à l'intérieur pour entreprendre, le contenu à implémenter au milieu doit renvoyer le css à utiliser, voici le noyau contenu:
...
const {
children,
direction,
wrap,
justifyContent,
alignItems,
alignContent,
span,
flex,
width,
height,
padding,
} = props;
...
return css`
box-sizing: border-box;
// direction
${direction != null &&
css`
flex-direction: ${direction};
`}
// wrap
${wrap != null &&
css`
flex-wrap: ${wrap};
`}
// justifyContent
${justifyContent != null &&
css`
justify-content: ${justifyContent};
`}
// ...
`
复制代码
Comme vous pouvez le voir, cela peut être réalisé simplement en ajoutant un css, ce qui est assez simple. Il convient d'expliquer que les propriétés des enfants ne sont pas déclarées publiquement, mais sont styled
implicitement rendues après avoir été transmises au composant généré.
Une fois créé, il peut être implémenté comme ceci en dehors du composant :
<Box direction="column" justifyContent="center">
<div>1</div>
<div>2</div>
<div>3</div>
</Box>
复制代码
Combiner
Le composant Combine est utilisé pour combiner différents composants. Semblable à Box, il s'agit toujours d'un composant basé sur le style. C'est une encapsulation de CSS pour la commodité de la mise en page. Nous n'utilisons pas flex, encapsulons simplement un tas d'éléments de bloc en ligne dans une grande div. src/components
Créez un nouveau Combine
dossier sous, créez un nouveau fichier sous le dossier index.tsx
:
const Combine = ({
children,
sharedProps = {},
spacing = 'smart',
separator,
...rest
}: CombineProps) => {
const { size = 'md' } = sharedProps;
let isFirstItem: boolean;
return (
<CombineWrap spacing={spacing} {...rest}>
{React.Children.map(children, (child) => (
// 遍历child
<>
// 放置分隔符
{separator && !isFirstItem ? <span className={separatorCls} key="separator">
{separator}
</span> : null
}
// 放置子元素
<div className={itemCls}>
{React.cloneElement(child)}
...
</div>
</>
)}
</CombineWrap>
)
}
复制代码
Le code ci-dessus définit les classes pour les éléments enfants et les séparateurs :
export const itemCls = prefixCls + '-item';
export const separatorCls = prefixCls + '-separator';
复制代码
Les composants reçoivent des paramètres d'espacement pour contrôler la distance entre les composants associés, et vous pouvez également définir des séparateurs comme séparateurs personnalisés. Voyons CombineWrap
l'implémentation du composant :
import styled from '@emotion/styled';
import { css } from '@emotion/core';
export const CombineWrap = styledWrap<{ spacing: string }>({
// 接受自定义class
className: prefixCls,
})(
// 生成一个自定义样式包裹的div
styled('div')((props) => {
const {
spacing,
theme: { designTokens: DT },
} = props;
// spacingMap为designTokens里定义的常量
const space = (DT as any)[spacingMap[spacing]];
return css`
display: inline-block; // inlink使得各个子元素平铺排列
vertical-align: middle;
// 子元素样式
> .${itemCls} {
&:focus {
z-index: 2;
}
&:hover {
z-index: 3;
}
}
// 子元素下一个兄弟,分隔符下一个子元素,子元素下一个分隔符 统一都加上左边距,这里就是space的用法
> .${itemCls}+.${itemCls}, > .${separatorCls}+.${itemCls}, > .${itemCls}+.${separatorCls} {
margin-left: ${space};
}
`;
}),
);
复制代码
Concernant les constantes d'espacement, vous pouvez définir des constantes dans le corps du thème :
T_SPACING_COMMON_XS: '4px',
T_SPACING_COMMON_SM: '8px',
T_SPACING_COMMON_MD: '12px',
T_SPACING_COMMON_LG: '16px',
T_SPACING_COMMON_XLG: '20px',
T_SPACING_COMMON_XXLG: '24px',
T_SPACING_COMMON_XXXLG: '32px',
复制代码
Ensuite, nous l'utilisons dans le projet :
<Combine>
<Button styleType="primary">按钮组展示</Button>
<Button>按钮组展示</Button>
<Button>按钮组展示</Button>
<Button disabled>按钮组展示</Button>
</Combine>
复制代码
Jusqu'à présent, les composants de mise en page Box
et Combine
l'introduction ont été complétés ~ Pour plus de composants, veuillez vous référer au référentiel de code : Référentiel Gitee