前言
这个组件github地址:github.com/lio-mengxia…
现在国内国外主流B端框架都会有一个叫布局的组件,如下图:
antd的布局组件示例如下:
element plus 布局组件示例如下:
用过的同学都知道,这些组件主要是帮助我们布局的,并且可以设置在不同屏幕尺寸下布局的样式。
组件的本质就是使用flex布局,假如我们要布局成如下样式,以上的布局组件实现起来比较麻烦,不妨你们尝试一下:
开始用felx写了一版,总感觉代码非常不优雅,条件判断很多,后来一想,我们是新项目,不兼容ie的,为啥不用grid布局呢,但是grid布局纯写css并不难,怎么把其封装成一个通用组件,并且使用起来要:
替代antd的grid组件! element plus 的layout组件!
问题就来了,市面上通用组件库都没这个组件啊,咋办,手写呗。参考开源项目 styled-css-grid,咋们用react函数式组件实现,并附有在线案例。因为代码只涉及到css封装,vue也可以借鉴然后封装自己的超强布局组件。
代码很优雅,只有两个文件。先看效果,再写源码, 一下所有案例的在线地址为: codesandbox.io/s/amazing-c…
案例一(这个案例的目的是说明我们组件具备子元素偏移的能力):
const cellStyle = {
fontSize: "0.8em",
border: "1px solid #999",
background: "#f5f2f0",
lineHeight: 1,
color: "#905"
};
export default function App() {
return (
<Grid columns={3} height={200}> <Cell center middle style={cellStyle}> Top Left </Cell> <Cell center middle style={cellStyle} left={3}> Top Right </Cell> <Cell center middle style={cellStyle} left={2} top={2}> Middle </Cell> <Cell center middle style={cellStyle} top={3}> Bottom Left </Cell> <Cell center middle style={cellStyle} top={3} left={3}> Bottom Right </Cell> </Grid>
);
}
案例2(这个案例说明我们的组件有任意分隔栅格布局的能力):
import { flatMap, range } from "lodash-es";
const cellStyle = {
fontSize: "0.8em",
border: "1px solid #999",
background: "#f5f2f0",
lineHeight: 1,
color: "#905"
};
const rows = (counts) =>
flatMap(counts, (number) =>
range(number).map((i) => (
<Cell center middle style={cellStyle} width={12 / number} key={`${number}_${i}`}> {i + 1}/{number} </Cell>
))
);
const TraditionalGrid = () => (
<article> <Grid columns={12} minRowHeight="45px"> {rows([12, 6, 4, 2, 1])} </Grid> </article>
);
案例三(代表我们组件具有奇形怪状的能力):
当然我们也具备本身flex的左对齐,右对齐,中间对齐这些功能:
以下是源码,一起交流:
实现GridLayout组件
import React, { useMemo } from 'react';
import { frGetter, autoRows, formatAreas } from '../config/functions';
const GridLayout = ({ columns, gap = '8px', columnGap, areas, minRowHeight, alignContent, rowGap, rows, justifyContent, flow, children, height = 'auto', style = {}, }: any) => {
const mergedstyle = {
display: 'grid', // 布局是grid布局
height, // 设置容器高度
gridAutoFlow: flow, // 设置容器内元素是从左往右(默认),还是从右往左
gridAutoRows: autoRows(minRowHeight), // grid-auto-rows设置默认单元格高度
gridTemplateRows: frGetter(rows), // 当传递一个数字时,它是指定行数的简写,平分高度,自适应。如果是例如100px,就是以这个数值为宽度
gridTemplateColumns: frGetter(columns), // 当传递一个数字时,它是指定列数的简写,平分宽度,自适应。 默认值为 12,如果是例如100px,就是以这个数值为宽度
columnGap, // 设置每个子元素之间列的间距
rowGap, // 设置每个子元素之间行的间距
areas: formatAreas(areas), // 传递一个字符串数组,例如 [“a a”,“b c”]。 默认不提供。
justifyContent, // 决定整个内容区域在容器里面的水平位置(左中右)
gridGap: gap, // 设置每个子元素之间的间距,默认8px
alignContent, // 决定整个内容区域的垂直位置(上中下)
...style,
};
return <div style={mergedstyle}>{children}</div>;
};
export default React.memo(GridLayout);
Cell组件
import React from 'react';
const middleStyle = (middle) => {
if (middle) {
return {
display: 'inline-flex',
flexFlow: 'column wrap',
justifyContent: 'center',
justifySelf: 'stretch',
};
}
};
const Cell = ({ width = 1, height = 1, area, middle, style = {}, left, top, center, children }: any) => {
const mergedstyle: any = {
height: '100%',
minWidth: 0,
gridColumnEnd: `span ${width}`, // 使用 grid-column-end 属性设置网格元素跨越多少列,或者在哪一列结束。
gridRowEnd: `span ${height}`, // grid-row-start 属性指定哪一行开始显示网格元素
gridColumnStart: left, // grid-column-start 属性定义了网格元素从哪一列开始
gridRowStart: top, // grid-row-end 属性指定哪一行停止显示网格元素,或设置跨越多少行
textAlign: center && 'center',
...middleStyle(middle),
...style,
};
if (area) mergedstyle.gridArea = area;
return <div style={mergedstyle}>{children}</div>;
};
export default React.memo(Cell);
工具函数:
export const autoRows = (minRowHeight = '20px') => `minmax(${minRowHeight}, auto)`;
export const frGetter = (value) => {
if (!value) return;
return typeof value === 'number' ? `repeat(${value}, 1fr)` : value;
};
export const formatAreas = (areas) => areas && areas.map((area) => `"${area}"`).join(' ');
今天的文章对不起,antd的Grid组件,element的Layout组件?过时了!分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/23571.html