Construire une bibliothèque d'interface utilisateur frontale basée sur React (4) - composants de mise en page

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/componentCréez un nouveau dossier sous le dossier et Boxcré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 BoxWrapcomposant :

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 styledimplicitement 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/componentsCréez un nouveau Combinedossier 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 CombineWrapl'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 Boxet Combinel'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

faire référence à

Espace et grille des composants React
Antd

Je suppose que tu aimes

Origine juejin.im/post/7082686023213252616
conseillé
Classement