Stack 堆叠布局组件 #
什么是 Stack? #
Stack 是一系列用于快速堆叠元素的布局组件,它会自动在子元素之间添加一致的间距。Chakra UI 提供了三种 Stack 组件:
- Stack:通用堆叠组件,可指定方向
- VStack:垂直堆叠
- HStack:水平堆叠
jsx
import { Stack, VStack, HStack } from '@chakra-ui/react'
function Example() {
return (
<VStack spacing={4}>
<Box>项目 1</Box>
<Box>项目 2</Box>
<Box>项目 3</Box>
</VStack>
)
}
VStack 垂直堆叠 #
基本用法 #
jsx
<VStack>
<Box w="100%" bg="blue.500" p={4}>项目 1</Box>
<Box w="100%" bg="green.500" p={4}>项目 2</Box>
<Box w="100%" bg="red.500" p={4}>项目 3</Box>
</VStack>
间距设置 #
jsx
<VStack spacing={2}>
<Box>间距 8px</Box>
</VStack>
<VStack spacing={4}>
<Box>间距 16px</Box>
</VStack>
<VStack spacing={8}>
<Box>间距 32px</Box>
</VStack>
对齐方式 #
jsx
<VStack align="stretch">
<Box>拉伸对齐</Box>
</VStack>
<VStack align="center">
<Box>居中对齐</Box>
</VStack>
<VStack align="flex-start">
<Box>起点对齐</Box>
</VStack>
HStack 水平堆叠 #
基本用法 #
jsx
<HStack>
<Box bg="blue.500" p={4}>项目 1</Box>
<Box bg="green.500" p={4}>项目 2</Box>
<Box bg="red.500" p={4}>项目 3</Box>
</HStack>
间距设置 #
jsx
<HStack spacing={2}>
<Box>间距 8px</Box>
</HStack>
<HStack spacing={4}>
<Box>间距 16px</Box>
</HStack>
<HStack spacing={8}>
<Box>间距 32px</Box>
</HStack>
对齐方式 #
jsx
<HStack align="flex-start">
<Box h="50px">起点对齐</Box>
<Box h="100px">起点对齐</Box>
</HStack>
<HStack align="center">
<Box h="50px">居中对齐</Box>
<Box h="100px">居中对齐</Box>
</HStack>
<HStack align="flex-end">
<Box h="50px">终点对齐</Box>
<Box h="100px">终点对齐</Box>
</HStack>
Stack 通用组件 #
指定方向 #
jsx
<Stack direction="row">
<Box>水平排列</Box>
</Stack>
<Stack direction="column">
<Box>垂直排列</Box>
</Stack>
响应式方向 #
jsx
<Stack
direction={{
base: 'column',
md: 'row'
}}
spacing={4}
>
<Box>项目 1</Box>
<Box>项目 2</Box>
<Box>项目 3</Box>
</Stack>
分隔符 #
jsx
<Stack divider={<StackDivider />} spacing={4}>
<Box>项目 1</Box>
<Box>项目 2</Box>
<Box>项目 3</Box>
</Stack>
<Stack
direction="row"
divider={<Box w="1px" h="20px" bg="gray.200" />}
spacing={4}
>
<Box>项目 1</Box>
<Box>项目 2</Box>
<Box>项目 3</Box>
</Stack>
常用布局示例 #
表单布局 #
jsx
function FormExample() {
return (
<VStack spacing={4} align="stretch">
<FormControl>
<FormLabel>姓名</FormLabel>
<Input placeholder="请输入姓名" />
</FormControl>
<FormControl>
<FormLabel>邮箱</FormLabel>
<Input type="email" placeholder="请输入邮箱" />
</FormControl>
<HStack spacing={4}>
<Button colorScheme="blue">提交</Button>
<Button variant="outline">取消</Button>
</HStack>
</VStack>
)
}
卡片列表 #
jsx
function CardList({ items }) {
return (
<VStack spacing={6} align="stretch">
{items.map((item) => (
<Card key={item.id}>
<CardBody>
<HStack>
<Avatar src={item.avatar} />
<Box flex="1">
<Text fontWeight="bold">{item.name}</Text>
<Text color="gray.500">{item.email}</Text>
</Box>
<Button size="sm" colorScheme="blue">
查看
</Button>
</HStack>
</CardBody>
</Card>
))}
</VStack>
)
}
导航栏 #
jsx
function Navbar() {
return (
<HStack justify="space-between" p={4} bg="white" shadow="sm">
<HStack spacing={8}>
<Logo />
<HStack as="nav" spacing={4}>
<Link href="#">首页</Link>
<Link href="#">功能</Link>
<Link href="#">价格</Link>
</HStack>
</HStack>
<HStack spacing={4}>
<Button variant="ghost">登录</Button>
<Button colorScheme="blue">注册</Button>
</HStack>
</HStack>
)
}
页脚链接 #
jsx
function Footer() {
return (
<VStack as="footer" py={8} bg="gray.100">
<HStack spacing={8}>
<Link href="#">关于我们</Link>
<Link href="#">联系方式</Link>
<Link href="#">隐私政策</Link>
<Link href="#">服务条款</Link>
</HStack>
<Text color="gray.500">© 2024 Company. All rights reserved.</Text>
</VStack>
)
}
用户信息卡片 #
jsx
function UserCard({ user }) {
return (
<HStack spacing={4} p={4} bg="white" borderRadius="md" shadow="sm">
<Avatar src={user.avatar} size="lg" />
<VStack align="start" spacing={1}>
<HStack>
<Text fontWeight="bold">{user.name}</Text>
<Badge colorScheme="green">在线</Badge>
</HStack>
<Text color="gray.500" fontSize="sm">{user.role}</Text>
<HStack spacing={2}>
<Icon as={FiMail} color="gray.400" />
<Text color="gray.500" fontSize="sm">{user.email}</Text>
</HStack>
</VStack>
</HStack>
)
}
统计数据展示 #
jsx
function StatsRow() {
return (
<HStack spacing={8} justify="center">
<VStack>
<Text fontSize="3xl" fontWeight="bold">1,234</Text>
<Text color="gray.500">用户</Text>
</VStack>
<VStack>
<Text fontSize="3xl" fontWeight="bold">567</Text>
<Text color="gray.500">订单</Text>
</VStack>
<VStack>
<Text fontSize="3xl" fontWeight="bold">¥89K</Text>
<Text color="gray.500">收入</Text>
</VStack>
</HStack>
)
}
响应式布局 #
响应式间距 #
jsx
<VStack
spacing={{
base: 2,
md: 4,
lg: 6
}}
>
<Box>项目 1</Box>
<Box>项目 2</Box>
</VStack>
响应式对齐 #
jsx
<VStack
align={{
base: 'center',
md: 'flex-start'
}}
>
<Box>项目 1</Box>
<Box>项目 2</Box>
</VStack>
堆叠转水平 #
jsx
<Stack
direction={{
base: 'column',
md: 'row'
}}
spacing={4}
>
<Box>项目 1</Box>
<Box>项目 2</Box>
<Box>项目 3</Box>
</Stack>
应该/不应该使用 Stack #
应该使用 #
jsx
<VStack spacing={4}>
<FormControl>...</FormControl>
<FormControl>...</FormControl>
<Button>提交</Button>
</VStack>
不应该使用 #
jsx
<VStack>
<Box mt={4}>项目 1</Box>
<Box mt={2}>项目 2</Box>
</VStack>
应该使用统一的 spacing:
jsx
<VStack spacing={4}>
<Box>项目 1</Box>
<Box>项目 2</Box>
</VStack>
Stack 属性速查表 #
| 属性 | 说明 | 默认值 |
|---|---|---|
| direction | 堆叠方向 | column |
| spacing | 间距 | 8px (2) |
| align | 交叉轴对齐 | stretch |
| justify | 主轴对齐 | flex-start |
| divider | 分隔符 | - |
| shouldWrapChildren | 包裹子元素 | false |
下一步 #
现在你已经掌握了 Stack 组件,接下来学习 Button 按钮,了解如何使用按钮组件!
最后更新:2026-03-28