ATRI
科幻连载中
<script setup lang="ts">
import { Button, Card, Flex, Heading, Tag } from '@hina-ui/vue'
</script>
<template>
<Card class="w-full max-w-lg">
<Flex justify="between" align="center" wrap class="gap-3">
<Flex direction="col" gap="xs">
<Heading :level="3" size="md">ATRI</Heading>
<Flex gap="xs">
<Tag>科幻</Tag>
<Tag>连载中</Tag>
</Flex>
</Flex>
<Flex gap="sm">
<Button variant="soft" tone="neutral">加入书架</Button>
<Button>开始阅读</Button>
</Flex>
</Flex>
</Card>
</template>
vue
用法
import { Flex } from '@hina-ui/vue'
ts
Flex 开放了 flex 布局的四个属性:direction、align、justify 和 wrap。方向固定时用 Stack 或 Inline 更简洁,需要切换方向或完整控制对齐时用 Flex。
<script setup lang="ts">
import { Card, Flex } from '@hina-ui/vue'
</script>
<template>
<Flex gap="sm">
<Card class="bg-inset size-10" :padded="false" />
<Card class="bg-inset size-10" :padded="false" />
<Card class="bg-inset size-10" :padded="false" />
</Flex>
</template>
vue
示例
方向
direction 有四个取值,默认横排。
row
1
2
3
row-reverse
1
2
3
col
1
2
3
col-reverse
1
2
3
<script setup lang="ts">
import { Card, Flex, Stack, Text } from '@hina-ui/vue'
const directions = ['row', 'row-reverse', 'col', 'col-reverse'] as const
</script>
<template>
<Flex gap="lg" wrap>
<Stack v-for="direction in directions" :key="direction" gap="xs">
<Text tone="muted" size="sm">{{ direction }}</Text>
<Flex :direction="direction" gap="sm" class="bg-inset rounded-md p-3">
<Card class="bg-surface grid size-8 place-items-center text-sm" :padded="false">1</Card>
<Card class="bg-surface grid size-8 place-items-center text-sm" :padded="false">2</Card>
<Card class="bg-surface grid size-8 place-items-center text-sm" :padded="false">3</Card>
</Flex>
</Stack>
</Flex>
</template>
vue
间距
gap 只接受档位。md 档随方向取值:横排取 --hn-inline-gap,纵排取 --hn-stack-gap,因此方向变化时无需调整间距。其余档位在两个方向上一致,分别是 0、4、8、24 和 32 像素。
横向的 md 档取 12 像素
纵向的 md 档取 16 像素
<script setup lang="ts">
import { Card, Flex, Stack, Text } from '@hina-ui/vue'
</script>
<template>
<Flex gap="xl" wrap>
<Stack gap="xs">
<Text tone="muted" size="sm">横向的 md 档取 12 像素</Text>
<Flex gap="md" class="bg-inset rounded-md p-3">
<Card class="bg-surface size-8" :padded="false" />
<Card class="bg-surface size-8" :padded="false" />
<Card class="bg-surface size-8" :padded="false" />
</Flex>
</Stack>
<Stack gap="xs">
<Text tone="muted" size="sm">纵向的 md 档取 16 像素</Text>
<Flex direction="col" gap="md" class="bg-inset rounded-md p-3">
<Card class="bg-surface size-8" :padded="false" />
<Card class="bg-surface size-8" :padded="false" />
<Card class="bg-surface size-8" :padded="false" />
</Flex>
</Stack>
</Flex>
</template>
vue
对齐与分布
align 控制交叉轴,justify 控制主轴。横排时 align 作用于纵向、justify 作用于横向,纵排时两者对调。
align 管交叉轴
start
center
end
stretch
justify 管主轴
<script setup lang="ts">
import { Card, Flex, Stack, Text } from '@hina-ui/vue'
const aligns = ['start', 'center', 'end', 'stretch'] as const
const justifies = ['start', 'center', 'end', 'between'] as const
</script>
<template>
<Stack>
<Stack gap="xs">
<Text tone="muted" size="sm">align 管交叉轴</Text>
<Flex gap="lg" wrap>
<Stack v-for="align in aligns" :key="align" gap="xs">
<Text tone="muted" size="sm">{{ align }}</Text>
<Flex :align="align" gap="sm" class="bg-inset h-24 rounded-md p-3">
<Card class="bg-surface h-8 w-8" :padded="false" />
<Card class="bg-surface h-12 w-8" :padded="false" />
</Flex>
</Stack>
</Flex>
</Stack>
<Stack gap="xs">
<Text tone="muted" size="sm">justify 管主轴</Text>
<Flex direction="col" gap="sm">
<Flex
v-for="justify in justifies"
:key="justify"
:justify="justify"
class="bg-inset w-64 rounded-md p-3"
>
<Card class="bg-surface size-8" :padded="false" />
<Card class="bg-surface size-8" :padded="false" />
</Flex>
</Flex>
</Stack>
</Stack>
</template>
vue
换行
不设置 wrap 时不换行,这是 flex 自身的行为。Inline 默认换行,Flex 则不默认换行。
wrap 为真时换行
默认不换行,保持在一行
<script setup lang="ts">
import { Card, Flex, Stack, Text } from '@hina-ui/vue'
const items = Array.from({ length: 10 }, (_, i) => i + 1)
</script>
<template>
<Stack class="w-full max-w-xs">
<Stack gap="xs">
<Text tone="muted" size="sm">wrap 为真时换行</Text>
<Flex wrap gap="sm">
<Card v-for="i in items" :key="i" class="bg-inset size-10" :padded="false" />
</Flex>
</Stack>
<Stack gap="xs">
<Text tone="muted" size="sm">默认不换行,保持在一行</Text>
<Flex gap="sm" class="overflow-hidden">
<Card v-for="i in items" :key="i" class="bg-inset size-10 shrink-0" :padded="false" />
</Flex>
</Stack>
</Stack>
</template>
vue
随断点变化
方向与对齐在不同断点下不同时,用 Tailwind 的断点类覆盖,例如 sm:flex-row。属性本身不接受响应式对象。
ATRI
窄屏时封面在上、文字在下,宽屏时并排。断点用 Tailwind 的类覆盖 direction。
<script setup lang="ts">
import { Card, Flex, Heading, Text } from '@hina-ui/vue'
</script>
<template>
<Flex direction="col" gap="md" class="w-full max-w-lg sm:flex-row sm:items-center">
<Card class="bg-inset h-24 shrink-0 sm:w-32" :padded="false" />
<Flex direction="col" gap="xs">
<Heading :level="3" size="md">ATRI</Heading>
<Text tone="muted" size="sm">
窄屏时封面在上、文字在下,宽屏时并排。断点用 Tailwind 的类覆盖 direction。
</Text>
</Flex>
</Flex>
</template>
vue
根元素
as 接受标签名或 Vue 组件,例如 as="section"、:as="RouterLink" 或 :as="NuxtLink"。组件须先导入或通过 resolveComponent 解析;对象组件、函数式组件和异步组件均可使用。布局类名、额外属性、事件监听器和默认插槽会传给该组件,不增加包裹层;自定义组件需将属性和类名传到实际根元素。
API
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
direction | 'row' | 'col' | 'row-reverse' | 'col-reverse' | 'row' | 主轴方向 |
gap | 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | — | 子元素之间的间距 |
align | 'start' | 'center' | 'end' | 'baseline' | 'stretch' | — | 交叉轴对齐方式 |
justify | 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly' | — | 主轴分布方式 |
wrap | boolean | — | 放不下时是否换行 |
as | string | Component | 'div' | 渲染的标签或 Vue 组件 |
class | string | — | 追加至容器的类名 |
| 插槽 | 说明 |
|---|---|
default | 子元素 |