可自定义设置以下属性:
对齐方式(align),类型:‘start’|‘end’|‘center’|‘baseline’,默认 undefined 间距方向(direction),类型:‘horizontal’|‘vertical’,默认: ‘horizontal’ 间距大小(size),数组时表示: [水平间距, 垂直间距],类型:number|number[]|‘small’|‘middle’|‘large’,默认 ‘small’ 是否自动换行(wrap),仅在 horizontal 时有效,类型:boolean,默认 false
效果如下图:
创建间距组件Space.vue
<script setup lang="ts">
import { computed } from 'vue'
interface Props {
align?: 'start'|'end'|'center'|'baseline' // 对齐方式
direction?: 'horizontal'|'vertical' // 间距方向
size?: number|number[]|'small'|'middle'|'large' // 间距大小,数组时表示: [水平间距, 垂直间距]
wrap?: boolean // 是否自动换行,仅在 horizontal 时有效
}
const props = withDefaults(defineProps<Props>(), {
align: undefined,
direction: 'horizontal',
size: 'small',
wrap: false
})
const gap = computed(() => {
if (typeof props.size === 'number') {
return props.size + 'px'
}
if (Array.isArray(props.size)) {
return props.size[1] + 'px ' + props.size[0] + 'px '
}
if (['small', 'middle', 'large'].includes(props.size)) {
const gapMap = {
small: '8px',
middle: '16px',
large: '24px'
}
return gapMap[props.size]
}
})
</script>
<template>
<div class="m-space" :class="[`${direction}`, {align: align, wrap: wrap}]" :style="`gap: ${gap}; margin-bottom: -${Array.isArray(props.size) && wrap ? props.size[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 .3s;
}
.horizontal {
flex-direction: row;
}
.vertical {
flex-direction: column;
}
.start {
align-items: flex-start;
}
.end {
align-items: flex-end;
}
.center {
align-items: center;
}
.baseline {
align-items: baseline;
}
.wrap {
flex-wrap: wrap;
}
</style>
在要使用的页面引入
<script setup lang="ts">
import { ref } from 'vue'
import Space from './Space.vue'
const options = ref([
{
label: 'small',
value: 'small'
},
{
label: 'middle',
value: 'middle',
},
{
label: 'large',
value: 'large'
}
])
const size = ref('small')
</script>
<template>
<div style="width: 500px;">
<h1>Space 间距</h1>
<h2 class="mt30 mb10">水平间距</h2>
<Radio :options="options" v-model:value="size" />
<br/><br/>
<Space :size="size">
<Button type="primary">Primary</Button>
<Button>Default</Button>
<Button type="dashed">Dashed</Button>
</Space>
<h2 class="mt30 mb10">垂直间距</h2>
<Space direction="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>
<Space :size="[8, 16]" wrap>
<template v-for="n in 10" :key="n">
<Button>Button</Button>
</template>
</Space>
</div>
</template>