【AI解读源码系列】ant design mobile——Space间距

前言

笔者目前业务主要围绕ant design mobile组件库来交付H5前端工作。

故此出此专栏来解读每一个组件是如何实现的。

本文基于AI来解读Space组件。

文档链接:

mobile.ant.design/zh/componen...

源码:

github.com/ant-design/...

设计prompt

arduino 复制代码
解读antd-mobile space组件,结构化思维输出整个组件实现流程,按步骤提供关键代码解读 

// 附组件代码

实现步骤

1. 目的

在子元素间插入可定制间距(horizontal / vertical / wrap / align / justify),通过 CSS 变量暴露 gap(--gap、--gap-horizontal、--gap-vertical)。


2. Props(关键)

ts 复制代码
export type SpaceProps = {
  direction?: 'horizontal' | 'vertical'           // 默认 'horizontal'
  align?: 'start' | 'end' | 'center' | 'baseline'
  justify?: 'start' | 'end' | 'center' | 'between' | 'around' | 'evenly' | 'stretch'
  wrap?: boolean
  block?: boolean
  onClick?: (e: React.MouseEvent<HTMLDivElement>) => void
  children?: React.ReactNode
} & NativeProps<'--gap' | '--gap-vertical' | '--gap-horizontal'>

默认:

ts 复制代码
const defaultProps = { direction: 'horizontal' }

3. 渲染逻辑(核心 JSX)

  • 合并默认 props(mergeProps)
  • 使用 withNativeProps 注入原生属性(style/className/data-*)
  • 每个子节点包裹为 .adm-space-item(过滤 null/undefined)

关键代码:

tsx 复制代码
export const Space: FC<SpaceProps> = p => {
  const props = mergeProps(defaultProps, p)
  const { direction, onClick } = props
  return withNativeProps(
    props,
    <div
      className={classNames('adm-space', {
        'adm-space-wrap': props.wrap,
        'adm-space-block': props.block,
        [`adm-space-${direction}`]: true,
        [`adm-space-align-${props.align}`]: !!props.align,
        [`adm-space-justify-${props.justify}`]: !!props.justify,
      })}
      onClick={onClick}
    >
      {React.Children.map(props.children, child =>
        child === null || child === undefined ? null : (
          <div className="adm-space-item">{child}</div>
        )
      )}
    </div>
  )
}

简短工具实现(可参考):

ts 复制代码
function mergeProps<T>(defaults: Partial<T>, props: T): T {
  return { ...(defaults as any), ...(props as any) }
}

function withNativeProps(props: any, node: React.ReactElement) {
  const { className, style, ...rest } = props
  return React.cloneElement(node, {
    ...rest,
    className: [node.props.className, className].filter(Boolean).join(' '),
    style: { ...(node.props.style || {}), ...(style || {}) },
  })
}

4. 样式核心(要点)

  • 使用 CSS 变量: --gap, --gap-horizontal, --gap-vertical
  • 默认 display: inline-flexblock 时为 display: flex
  • .adm-space-item { flex: none } 保证子项不被拉伸
  • vertical:item 用 margin-bottom,最后一个取消
  • horizontal:item 用 margin-right,容器用负 margin-right 抵消末尾多余空隙
  • wrap:flex-wrap: wrap + 外层负 margin-bottom + item padding-bottom 实现行间距

简要 CSS:

css 复制代码
.adm-space {
  display: inline-flex;
  --gap: 8px;
  --gap-horizontal: var(--gap);
  --gap-vertical: var(--gap);
}
.adm-space-item { flex: none; }

.adm-space-horizontal { flex-direction: row; }
.adm-space-horizontal > .adm-space-item { margin-right: var(--gap-horizontal); }
.adm-space-horizontal:not(:empty) { margin-right: calc(var(--gap-horizontal) * -1); }

.adm-space-vertical { flex-direction: column; }
.adm-space-vertical > .adm-space-item { margin-bottom: var(--gap-vertical); }
.adm-space-vertical > .adm-space-item:last-child { margin-bottom: 0; }

.adm-space-wrap { flex-wrap: wrap; margin-bottom: calc(var(--gap-vertical) * -1); }
.adm-space-wrap > .adm-space-item { padding-bottom: var(--gap-vertical); }

/* align / justify 映射到 align-items / justify-content */

5. 使用示例

tsx 复制代码
<Space>
  <Button>按钮1</Button>
  <Button>按钮2</Button>
</Space>

<Space direction="vertical" style={{ '--gap': '16px' }}>
  <div>行1</div>
  <div>行2</div>
</Space>

<Space wrap style={{ '--gap-horizontal': '12px', '--gap-vertical': '8px' }}>
  {items.map(i => <Tag key={i}>{i}</Tag>)}
</Space>

自定义 gap:

tsx 复制代码
<Space style={{ '--gap': '12px' }} />

简单替代(现代浏览器支持 flex gap):

tsx 复制代码
const SimpleSpace = ({children, gap='8px'}) => (
  <div style={{display:'inline-flex', gap}}>
    {React.Children.toArray(children).map((c,i)=> <div style={{flex:'none'}} key={i}>{c}</div>)}
  </div>
)

6. 关键设计理由(一句话)

通过包裹子项 + flex: none + margin/padding 组合,利用 CSS 变量暴露 gap,做到间距可控且不影响子元素布局;负 margin 处理容器末尾多余空隙。

以上就是笔者基于AI返回的解读信息稍加了一些补充和修改,结合起来看源码提效真是太多了,对于前端本身就是基于视图所完成编码,因此把组件逻辑层交给AI来解读太适合不过了。

希望对大家有所帮助,共同学习源码。

相关推荐
RANCE_atttackkk4 分钟前
[Java]实现使用邮箱找回密码的功能
java·开发语言·前端·spring boot·intellij-idea·idea
摘星编程43 分钟前
React Native + OpenHarmony:Timeline垂直时间轴
javascript·react native·react.js
2501_944525542 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 支出分析页面
android·开发语言·前端·javascript·flutter
jin1233222 小时前
React Native鸿蒙跨平台完成剧本杀组队详情页面,可以复用桌游、团建、赛事等各类组队详情页开发
javascript·react native·react.js·ecmascript·harmonyos
李白你好2 小时前
Burp Suite插件用于自动检测Web应用程序中的未授权访问漏洞
前端
经年未远3 小时前
vue3中实现耳机和扬声器切换方案
javascript·学习·vue
刘一说3 小时前
Vue 组件不必要的重新渲染问题解析:为什么子组件总在“无故”刷新?
前端·javascript·vue.js
jin1233223 小时前
基于React Native鸿蒙跨平台移动端表单类 CRUD 应用,涵盖地址列表展示、新增/编辑/删除/设为默认等核心操作
react native·react.js·ecmascript·harmonyos
可触的未来,发芽的智生3 小时前
狂想:为AGI代称造字ta,《第三类智慧存在,神的赐名》
javascript·人工智能·python·神经网络·程序人生
徐同保4 小时前
React useRef 完全指南:在异步回调中访问最新的 props/state引言
前端·javascript·react.js