Vant Space 间距组件:5 个 Props 搞定元素间距,还能分别设置横向纵向间距
2026/9/19 13:15:47 网站建设 项目流程

Vant Space 间距组件:5 个 Props 搞定元素间距,还能分别设置横向纵向间距

【免费下载链接】vantA lightweight, customizable Vue UI library for mobile web apps.项目地址: https://gitcode.com/GitHub_Trending/va/vant

在 Vant 中,van-space是专门负责"元素之间间距"的布局组件:把子元素包进<van-space>,组件会自动在每个子元素之间注入统一间距,横向、纵向、换行行距都可以单独控制,不需要你再给子元素手工补 margin。

快速接入:安装并渲染第一个 van-space

先安装 Vant 并注册组件,然后把子元素直接放进<van-space>

import { createApp } from 'vue'; import { Space } from 'vant'; const app = createApp(); app.use(Space);
<van-space> <van-button type="primary">按钮</van-button> <van-button type="primary">按钮</van-button> <van-button type="primary">按钮</van-button> </van-space>

不传任何属性时,子元素之间会自动出现8px 的横向间距(默认值来自packages/vant/src/space/Space.tsxsizedefault: 8)。除全局注册外,也可以按需import { Space } from 'vant'后在组件里局部注册,用法一致。

横向按钮组:默认行为就够了

问题:一行按钮要拉开间距,又不想在每个按钮上写margin-right

代码:就是上面的基础用法,什么都不用传。组件会为每个子元素包一层.van-space-item,用内联样式注入margin-right: 8px,末项不注入,所以按钮组两端不会多出空白。

关键点:间距是加在"包裹层"上的,不会污染子组件自身样式;子元素高度不一致时,默认按align-items: center垂直居中(见下文对齐一节)。

纵向通栏列表:direction="vertical" 搭配 fill 和 block

问题:按钮、卡片需要纵向排成一列并占满整行宽度。

<van-space direction="vertical" fill> <van-button type="primary" block>按钮</van-button> <van-button type="primary" block>按钮</van-button> <van-button type="primary" block>按钮</van-button> </van-space>

三个属性缺一不可地配合:

  • direction="vertical":容器切换为flex-direction: column,间距从margin-right换成margin-bottom
  • fill:Space 默认是display: inline-flex,宽度由内容撑开;加上fill后变成display: flex块级容器,才能撑满父元素;
  • 子元素加block:Button 默认是自适应宽度,通栏效果需要子元素自己撑满。

如何分别设置横向纵向间距:size 的三种写法

size支持三种形态,对应三种诉求:

<!-- 数字:自动补 px --> <van-space :size="20">...</van-space> <!-- 字符串:自带单位,原样使用 --> <van-space size="2rem">...</van-space> <!-- 数组:[横向间距, 纵向间距],配合 wrap 分别控制列距和行距 --> <van-space wrap :size="[12, 20]">...</van-space>

数组形态是size最实用的隐藏能力:size[0]决定margin-rightsize[1]决定margin-bottom。在wrap模式下每个子项都会同时携带横向与纵向两个 margin,正好对应"列距"和"行距"两个概念。字符串类型请带单位(如20px2em5vw),组件不会替你补。

对齐方式:align 的四种取值与默认行为

问题:按钮和高块元素并排时,垂直方向怎么对齐。

<van-space align="start" style="padding: 16px; background: #f3f2f5"> <van-button type="primary">按钮</van-button> <div style="padding: 40px 20px; background: #fff">Block</div> </van-space>

align可选startcenterendbaseline,映射为align-items: flex-start / center / flex-end / baseline注意默认值取决于方向:水平模式不传align时默认按center处理,垂直模式不传则不加对齐类(纵向排列中align-items影响不大)。所以align主要服务于水平模式。

自动换行:wrap 之后行距从哪来

问题:子元素多、一行放不下时,折行后第二行会紧贴第一行,没有行距。

<van-space wrap :size="[12, 16]"> <!-- 大量子元素,一行放不下时自动折行 --> </van-space>

开启wrap后容器加上flex-wrap: wrap。行距的保证方式是:开启wrap所有子项(包括最后一项)都会注入margin-bottom,这样每一行的高度天然包含行距,折行后第二行不会贴住第一行。横向间距仍由margin-right提供,只是换到新一行时该行不再受上一行末项的margin-right影响——这正是size数组形态存在的原因。

API 速查

Props

参数说明类型默认值
direction间距方向vertical | horizontalhorizontal
size间距大小,如20px2em;数字默认补px单位;数组形式[横向间距, 纵向间距]number | string | [number | string, number | string]8
align子元素对齐方式start | end | center | baseline水平模式center,垂直模式无
wrap是否自动换行,仅水平方向有效booleanfalse
fill是否变为块级元素,填充整个父元素宽度booleanfalse

Slots

名称说明
default间距组件内容

类型定义

import type { SpaceProps, SpaceSize, SpaceAlign } from 'vant';

推荐组合:纵向通栏用direction="vertical" + fill + 子元素 block;标签墙、筛选按钮组用wrap + size 数组;纯横向小组合直接裸用即可。wrap只对水平方向有意义,垂直模式下没有"换行"概念。

内部实现:间距到底是怎么注入的

Space 的全部逻辑集中在 packages/vant/src/space/Space.tsx,样式在 packages/vant/src/space/index.less,四个实现点决定了它的行为边界:

  1. 间距是内联 margin,不是 CSS 变量。渲染时每个子元素被包进.van-space-item,由getMarginStyle计算内联样式:水平方向写margin-right,垂直方向或开启wrap时写margin-bottom。因此子项数量变化、动态渲染都能即时生效,不依赖兄弟选择器。
  2. 最后一项特殊处理getMarginStyle(isLast)对末项默认返回空样式,避免行尾/列尾出现多余空白;唯独wrap模式下末项保留margin-bottom,否则最后一行高度缺行距,下一行会贴上来。
  3. 空节点过滤filterEmpty递归展开 Fragment,剔除注释节点、空 Fragment 和纯空白文本节点。没有这一步,<van-space><A /><B /></van-space>中换行产生的文本节点会占据一个间距位,导致间距数量与子元素数量对不上。
  4. 类名走 BEM 规则createNamespace('space')生成的bemdirectionalignwrapfill映射为van-space--verticalvan-space--align-centervan-space--wrapvan-space--fill等类名;align缺省时由mergedAlign计算属性回退为水平模式的'center'

单元测试(packages/vant/src/space/test/index.spec.tsx)覆盖了默认 8px 右间距、末项无间距、垂直排列类名与下间距、自定义20pxalignwrap类名等核心行为;demo.spec.ts则以快照方式锁定演示页渲染结果。

避坑与最佳实践

  • fillinline-flex的宽度差异:不开fill时 Space 是行内 Flex,宽度由内容决定,垂直模式下的子元素不会撑满父容器;需要通栏必须fill和子元素block同时给。
  • size传字符串要带单位:数字才会自动补pxsize="2rem"原样生效,size="20"会变成非法值20
  • wrap模式下末项也有margin-bottom:这是刻意行为(保证行距一致),如果容器本身又加了padding-bottom,注意叠加后的底部空隙。
  • align只对水平模式有明显意义:垂直模式下align-items作用在纵向轴上,通常无需设置。
  • TS 项目用SpaceProps标注 props 对象SpaceSizeSpaceAlign可用于局部类型收窄,均从vant包根路径导入。

间距场景优先用van-space而不是手工 margin:间距语义集中在一处,增删子元素时布局不会错位,横纵、换行这些边界情况也已由组件内部处理完毕。

【免费下载链接】vantA lightweight, customizable Vue UI library for mobile web apps.项目地址: https://gitcode.com/GitHub_Trending/va/vant

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询