Skip to content

弹性布局 Flex ​

赞助

设置组件之间的间距,设置各种水平、垂直对齐方式

与 Space 组件的区别 ​

  • Space 为内联元素提供间距,自身以 inline-flex 排列子元素(不额外包裹),适用于行内多个元素的等距排列。
  • Flex 为块级元素提供间距,自身以 flex 排列子元素,适用于垂直或水平方向上的布局,并提供了更多的灵活性和控制能力。

基本使用 ​

通过 vertical 切换主轴方向


Show Code
vue
<script setup lang="ts">
import { ref } from 'vue'
const directionOptions = ref([
  {
    label: 'horizontal',
    value: 'horizontal'
  },
  {
    label: 'vertical',
    value: 'vertical'
  }
])
const direction = ref('horizontal')
const baseStyle = {
  width: '25%',
  height: '54px'
}
</script>
<template>
  <Flex vertical>
    <RadioGroup :options="directionOptions" v-model:value="direction" />
    <Flex :vertical="direction === 'vertical'">
      <div v-for="n in 4" :key="n" :style="{ ...baseStyle, background: `${n % 2 ? '#1677ffbf' : '#1677ff'}` }" />
    </Flex>
  </Flex>
</template>

对齐方式 ​

通过 justify 与 align 分别控制主轴与交叉轴的对齐方式


justify:
align:
Primary
Primary
Primary
Primary
Show Code
vue
<script setup lang="ts">
import { ref } from 'vue'
const justifyOptions = ref([
  {
    label: 'flex-start',
    value: 'flex-start'
  },
  {
    label: 'center',
    value: 'center'
  },
  {
    label: 'flex-end',
    value: 'flex-end'
  },
  {
    label: 'space-between',
    value: 'space-between'
  },
  {
    label: 'space-around',
    value: 'space-around'
  },
  {
    label: 'space-evenly',
    value: 'space-evenly'
  }
])
const alignOptions = ref([
  {
    label: 'flex-start',
    value: 'flex-start'
  },
  {
    label: 'center',
    value: 'center'
  },
  {
    label: 'flex-end',
    value: 'flex-end'
  }
])
const justify = ref(justifyOptions.value[0].value)
const alignItems = ref(alignOptions.value[0].value)
const boxStyle = {
  width: '100%',
  height: '120px',
  borderRadius: '6px',
  border: '1px solid #40a9ff'
}
</script>
<template>
  <Flex vertical :gap="12">
    <Flex vertical :gap="4">
      <span>justify:</span>
      <RadioGroup v-model:value="justify" button :options="justifyOptions" />
    </Flex>
    <Flex vertical :gap="4">
      <span>align:</span>
      <RadioGroup v-model:value="alignItems" button :options="alignOptions" />
    </Flex>
    <Flex :style="{ ...boxStyle }" :justify="justify" :align="alignItems">
      <Button type="primary">Primary</Button>
      <Button type="primary">Primary</Button>
      <Button type="primary">Primary</Button>
      <Button type="primary">Primary</Button>
    </Flex>
  </Flex>
</template>

设置间距 ​

通过 gap 设置间距,可选档位或自定义数值


Primary
Default
Dashed
Show Code
vue
<script setup lang="ts">
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>
  <Flex vertical>
    <RadioGroup :options="gapOptions" v-model:value="gapSize" />
    <Slider v-if="gapSize === 'customize'" v-model:value="customGapSize" />
    <Flex :gap="gapSize !== 'customize' ? gapSize : customGapSize">
      <Button type="primary">Primary</Button>
      <Button>Default</Button>
      <Button type="dashed">Dashed</Button>
      <Button type="link">Link</Button>
    </Flex>
  </Flex>
</template>

自动换行 ​

wrap 开启换行,width 限定容器宽度,gap 数组分别设置水平与垂直间距


Button
Button
Button
Button
Button
Button
Button
Button
Button
Button
Button
Button
Button
Button
Button
Button

Show Code
vue
<template>
  <Flex wrap="wrap" :width="600" :gap="[8, 16]">
    <Button v-for="n in 16" :key="n" type="primary">Button</Button>
  </Flex>
</template>

自定义标签 ​

通过 component 指定渲染的标签或组件,便于语义化布局


  • 列表项 1
  • 列表项 2
  • 列表项 3
Show Code
vue
<template>
  <Flex component="ul" vertical :gap="8" class="flex-list">
    <li v-for="n in 3" :key="n">列表项 {{ n }}</li>
  </Flex>
</template>
<style lang="less" scoped>
.flex-list {
  padding: 0;
  margin: 0;
  list-style: none;
  li {
    padding: 8px 12px;
    background: var(--va-fill-color-1);
    border-radius: 6px;
  }
}
</style>

容器伸缩 ​

通过 flex 设置容器自身作为 flex 子项时的伸缩比,示例两块按 1 : 2 分配剩余宽度,无需另写 style


flex: 1
flex: 2
Show Code
vue
<template>
  <Flex gap="small">
    <Flex flex="1" justify="center" align="center" class="flex-stretch-demo">flex: 1</Flex>
    <Flex flex="2" justify="center" align="center" class="flex-stretch-demo">flex: 2</Flex>
  </Flex>
</template>
<style lang="less" scoped>
.flex-stretch-demo {
  height: 64px;
  font-size: 14px;
  font-weight: 500;
  color: var(--va-primary-color);
  background: var(--va-primary-bg-color);
  border-radius: 8px;
}
</style>

组合使用 ​

嵌套使用可实现更复杂的布局,主轴与交叉轴可分别控制


“Vue Amazing UI is an enterprise-class UI library built with Vue 3 and TypeScript.”

Get Started
Show Code
vue
<template>
  <Card :style="{ width: '620px', maxWidth: '100%' }" :body-style="{ padding: 0, overflow: 'hidden' }">
    <Flex justify="space-between">
      <img
        class="flex-combination-logo"
        src="https://themusecatcher.github.io/vue-amazing-ui/amazing-logo.svg"
        alt="Vue Amazing UI"
      />
      <Flex vertical align="flex-end" justify="space-between" class="flex-combination-body">
        <p class="flex-combination-quote"
          >“Vue Amazing UI is an enterprise-class UI library built with Vue 3 and TypeScript.”</p
        >
        <Button type="primary" href="https://themusecatcher.github.io/vue-amazing-ui/" target="_blank"
          >Get Started</Button
        >
      </Flex>
    </Flex>
  </Card>
</template>
<style lang="less" scoped>
.flex-combination-logo {
  display: block;
  width: 273px;
  height: 273px;
  object-fit: contain;
}
.flex-combination-body {
  flex: 1;
  padding: 32px;
}
.flex-combination-quote {
  margin: 0;
  font-size: 24px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--va-text-color-1);
}
</style>

APIs ​

Flex Props ​

名称说明类型默认值
width弹性区域总宽度,单位 pxstring | number'auto'
flex容器自身作为 flex 子项时的伸缩简写,数值即 flex-grow,字符串原样透传string | numberundefined
verticalflex 主轴的方向是否垂直,vertical 使用 flex-direction: columnbooleanfalse
wrap设置元素单行显示还是多行显示;参考 flex-wrap'nowrap' | 'wrap' | 'wrap-reverse''nowrap'
justify设置元素在主轴方向上的对齐方式;参考 justify-contentstring'normal'
align设置元素在交叉轴方向上的对齐方式;参考 align-itemsstring'normal'
gap间距大小,数组时表示: [水平间距, 垂直间距]number | number[] | 'small' | 'middle' | 'large''middle'
component渲染的标签名或组件,用于语义化布局string | Component'div'

无子元素时不参与布局(不占父级 flex 的一份间距)。

Slots ​

名称说明用法
default自定义内容v-slot:default

Released under the MIT License.