封装grid布局

198 阅读1分钟

效果

image.png

用法

  import { GridLayout, GridCell } from '@/components/Grid'

  <GridLayout
    padding="20px"
    height="100%"
    flow="row"
    rows={10}
    columns={10}
    gap="10px"
    border
  >
    <GridCell height={1}>1</GridCell>
    <GridCell width={3} height={5}>
      2
    </GridCell>
    <GridCell width={2} height={3} center>
      3
    </GridCell>
    <GridCell width={4}>4</GridCell>
    <GridCell width={2} height={2}>
      5
    </GridCell>
    <GridCell left={7} top={7} width={2} height={3}>
      6
    </GridCell>
  </GridLayout>

属性

  1. padding:就是padding的属性
  2. flow:grid-auto-flow属性,代表先行后列还是先列后行
  3. rows:垂直的格子数量
  4. columns:水平的格子数量
  5. gap:行列之间的间距,和gap属性一样,可以设置合并简写

GridCell属性

left和top就代表从哪个网格线开始,width和height就是占据多少网格线

完整代码

  setup(props, { slots }) {
    const repeatString = (str: string, num: number) =>
      Array.from({ length: num }, () => str).join(' ')

    provide('grid', props)

    const styles = [
      `width: ${props.width}`,
      `height: ${props.height}`,
      `padding: ${props.padding}`,
      `display: ${props.inline ? 'inline-grid' : 'grid'}`,
      `grid-template-columns: ${repeatString('1fr', props.columns)}`,
      `grid-template-rows: ${repeatString('1fr', props.rows)}`,
      `grid-auto-flow: ${props.flow}`,
      `gap: ${props.gap}`
    ]
    return () => {
      return <div style={styles}>{slots.default && slots.default()}</div>
    }
  }
  setup(props, { slots }) {
    const { border }: any = inject('grid')

    const center = [
      'display: flex',
      'justify-content: center',
      'align-items: center'
    ]

    const styles = [
      `grid-column: span ${props.width}`,
      `grid-row: span ${props.height}`,
      props.center ? center : '',
      ...(props.left && props.width
        ? [`grid-column: ${props.left} / span ${props.width}`]
        : []),
      ...(props.top && props.height
        ? [`grid-row: ${props.top} / span ${props.height}`]
        : []),
      border ? 'border: 1px solid #ccc' : ''
    ]

    return () => {
      return <div style={styles}>{slots.default && slots.default()}</div>
    }
  }