APIs
Space
参数 |
说明 |
类型 |
默认值 |
width |
区域总宽度,单位 px |
string | number |
‘auto’ |
align |
垂直排列方式 |
‘stretch’ | ‘start’ | ‘end’ | ‘center’ | ‘baseline’ |
‘start’ |
vertical |
是否为垂直布局 |
boolean |
false |
gap |
间距大小,数组时表示: [水平间距, 垂直间距] |
number | number[] | ‘small’ | ‘middle’ | ‘large’ |
‘middle’ |
wrap |
是否自动换行,仅在 horizontal 时有效 |
boolean |
true |
创建间距组件Space.vue
<script setup lang="ts">
import { computed } from 'vue'
interface Props {
width?: string | number // 区域总宽度,单位 px
align?: 'stretch' | 'start' | 'end' | 'center' | 'baseline' // 垂直排列方式
vertical?: boolean // 是否为垂直布局
gap?: number | number[] | 'small' | 'middle' | 'large' // 间距大小,数组时表示: [水平间距, 垂直间距]
wrap?: boolean // 是否自动换行,仅在 horizontal 时有效
}
const props = withDefaults(defineProps<Props>(), {
width: 'auto',
align: 'start',
vertical: false,
gap: 'middle',
wrap: true
})
const spaceWidth = computed(() => {
if (typeof props.width === 'number') {
return props.width + 'px'
}
return props.width
})
const gapValue = computed(() => {
if (typeof props.gap === 'number') {
return props.gap + 'px'
}
if (Array.isArray(props.gap)) {
return props.gap[1] + 'px ' + props.gap[0] + 'px '
}
if (['small', 'middle', 'large'].includes(props.gap)) {
const gapMap = {
small: '8px',
middle: '16px',
large: '24px'
}
return gapMap[props.gap]
}
})
</script>
<template>
<div
class="m-space"
:class="[`space-${align}`, { 'space-vertical': vertical, 'space-wrap': wrap }]"
:style="`width: ${spaceWidth}; gap: ${gapValue}; margin-bottom: -${Array.isArray(props.gap) && wrap ? props.gap[1] : 0}px;`"
>
<slot></slot>
</div>
</template>
<style lang="less" scoped>
.m-space {
display: inline-flex;
font-size: 14px;
color: rgba(0, 0, 0, 0.88);
transition: all 0.3s;
flex-direction: row;
}
.space-vertical {
flex-direction: column;
}
.space-stretch {
align-items: stretch;
}
.space-start {
align-items: flex-start;
}
.space-end {
align-items: flex-end;
}
.space-center {
align-items: center;
}
.space-baseline {
align-items: baseline;
}
.space-wrap {
flex-wrap: wrap;
}
</style>
在要使用的页面引入
<script setup lang="ts">
import Space from './Space.vue'
import { ref } from 'vue'
const gapOptions = ref([
{
label: 'small',
value: 'small'
},
{
label: 'middle',
value: 'middle'
},
{
label: 'large',
value: 'large'
},
{
label: 'customize',
value: 'customize'
}
])
const gapSize = ref('middle')
const customGapSize = ref(16)
</script>
<template>
<div>
<h1>{
{ $route.name }} {
{ $route.meta.title }}</h1>
<h2 class="mt30 mb10">基本使用</h2>
<Space align="center">
Space
<Button type="primary">Button</Button>
<Popconfirm title="Are you sure delete this task?" ok-text="Yes" cancel-text="No">
<Button>Confirm</Button>
</Popconfirm>
</Space>
<h2 class="mt30 mb10">设置间距</h2>
<Flex vertical>
<Radio :options="gapOptions" v-model:value="gapSize" />
<Slider v-if="gapSize === 'customize'" v-model:value="customGapSize" />
<Space :gap="gapSize !== 'customize' ? gapSize : customGapSize">
<Button type="primary">Primary</Button>
<Button>Default</Button>
<Button type="dashed">Dashed</Button>
<Button type="link">Link</Button>
</Space>
</Flex>
<h2 class="mt30 mb10">垂直间距</h2>
<Space vertical>
<Card title="Card" style="width: 300px">
<p>Card content</p>
<p>Card content</p>
</Card>
<Card title="Card" style="width: 300px">
<p>Card content</p>
<p>Card content</p>
</Card>
</Space>
<h2 class="mt30 mb10">对齐</h2>
<div class="space-align-container">
<div class="space-align-block">
<Space align="center">
center
<Button type="primary">Primary</Button>
<span class="mock-block">Block</span>
</Space>
</div>
<div class="space-align-block">
<Space align="start">
start
<Button type="primary">Primary</Button>
<span class="mock-block">Block</span>
</Space>
</div>
<div class="space-align-block">
<Space align="end">
end
<Button type="primary">Primary</Button>
<span class="mock-block">Block</span>
</Space>
</div>
<div class="space-align-block">
<Space align="baseline">
baseline
<Button type="primary">Primary</Button>
<span class="mock-block">Block</span>
</Space>
</div>
</div>
<h2 class="mt30 mb10">自动换行</h2>
<Space :gap="[8, 16]" style="width: 600px">
<template v-for="n in 16" :key="n">
<Button type="primary">Button</Button>
</template>
</Space>
</div>
</template>
<style lang="less" scoped>
.space-align-container {
display: flex;
align-items: flex-start;
flex-wrap: wrap;
}
.space-align-block {
margin: 8px 4px;
border: 1px solid #40a9ff;
padding: 4px;
flex: none;
}
.space-align-block .mock-block {
display: inline-block;
padding: 32px 8px 16px;
background: rgba(150, 150, 150, 0.2);
}
</style>