Chakra Factory 组件工厂 #
什么是 Chakra Factory? #
Chakra Factory 是一个强大的工具函数,它可以将任意 HTML 元素或第三方组件转换为支持 Chakra Style Props 的组件。
jsx
import { chakra } from '@chakra-ui/react'
const StyledSection = chakra('section')
function App() {
return (
<StyledSection p={4} bg="blue.500" color="white">
支持 Style Props 的 section 元素
</StyledSection>
)
}
基本用法 #
转换 HTML 元素 #
jsx
import { chakra } from '@chakra-ui/react'
const StyledHeader = chakra('header')
const StyledFooter = chakra('footer')
const StyledNav = chakra('nav')
const StyledArticle = chakra('article')
function BlogPost() {
return (
<StyledHeader bg="gray.100" p={4}>
<StyledNav display="flex" gap={4}>
导航栏
</StyledNav>
</StyledHeader>
)
}
转换第三方组件 #
jsx
import { chakra } from '@chakra-ui/react'
import { Link as RouterLink } from 'react-router-dom'
const StyledLink = chakra(RouterLink)
function Navigation() {
return (
<StyledLink
to="/home"
color="blue.500"
_hover={{ color: 'blue.600' }}
fontWeight="medium"
>
首页
</StyledLink>
)
}
chakra 函数 #
语法 #
jsx
chakra(element, options?)
参数 #
| 参数 | 类型 | 说明 |
|---|---|---|
| element | string | ReactComponent | HTML 标签名或 React 组件 |
| options | object | 配置选项 |
示例 #
jsx
import { chakra } from '@chakra-ui/react'
const StyledButton = chakra('button', {
baseStyle: {
px: 4,
py: 2,
borderRadius: 'md',
fontWeight: 'medium',
},
})
内置 Chakra 元素 #
Chakra UI 已经为所有 HTML 元素提供了 chakra 版本:
jsx
import { chakra } from '@chakra-ui/react'
function App() {
return (
<chakra.div p={4} bg="gray.100">
<chakra.h1 fontSize="2xl" mb={4}>
标题
</chakra.h1>
<chakra.p color="gray.600">
段落内容
</chakra.p>
<chakra.button
mt={4}
px={4}
py={2}
bg="blue.500"
color="white"
borderRadius="md"
_hover={{ bg: 'blue.600' }}
>
按钮
</chakra.button>
</chakra.div>
)
}
可用的 Chakra 元素 #
jsx
<chakra.div />
<chakra.span />
<chakra.p />
<chakra.h1 />
<chakra.h2 />
<chakra.h3 />
<chakra.h4 />
<chakra.h5 />
<chakra.h6 />
<chakra.button />
<chakra.input />
<chakra.textarea />
<chakra.select />
<chakra.a />
<chakra.img />
<chakra.ul />
<chakra.ol />
<chakra.li />
<chakra.table />
<chakra.thead />
<chakra.tbody />
<chakra.tr />
<chakra.td />
<chakra.th />
<chakra.form />
<chakra.label />
<chakra.section />
<chakra.article />
<chakra.header />
<chakra.footer />
<chakra.nav />
<chakra.main />
<chakra.aside />
创建可复用组件 #
基础组件 #
jsx
import { chakra } from '@chakra-ui/react'
export const Card = chakra('div', {
baseStyle: {
p: 6,
bg: 'white',
borderRadius: 'lg',
shadow: 'md',
},
})
export const CardTitle = chakra('h3', {
baseStyle: {
fontSize: 'xl',
fontWeight: 'bold',
mb: 2,
},
})
export const CardText = chakra('p', {
baseStyle: {
color: 'gray.600',
lineHeight: 'tall',
},
})
使用组件 #
jsx
import { Card, CardTitle, CardText } from './components'
function ProductCard() {
return (
<Card>
<CardTitle>产品名称</CardTitle>
<CardText>产品描述信息</CardText>
</Card>
)
}
与第三方库集成 #
React Router #
jsx
import { chakra } from '@chakra-ui/react'
import { Link as RouterLink, NavLink as RouterNavLink } from 'react-router-dom'
export const Link = chakra(RouterLink, {
baseStyle: {
color: 'blue.500',
textDecoration: 'none',
_hover: {
textDecoration: 'underline',
},
},
})
export const NavLink = chakra(RouterNavLink, {
baseStyle: {
px: 3,
py: 2,
borderRadius: 'md',
color: 'gray.600',
_hover: {
bg: 'gray.100',
},
_activeLink: {
bg: 'blue.50',
color: 'blue.600',
},
},
})
Framer Motion #
jsx
import { chakra } from '@chakra-ui/react'
import { motion } from 'framer-motion'
const MotionBox = chakra(motion.div)
function AnimatedCard() {
return (
<MotionBox
p={6}
bg="white"
borderRadius="lg"
shadow="md"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.3 }}
>
动画卡片
</MotionBox>
)
}
React Icons #
jsx
import { chakra } from '@chakra-ui/react'
import { FiHome, FiUser, FiSettings } from 'react-icons/fi'
const Icon = chakra(FiHome)
function IconExample() {
return (
<>
<Icon boxSize={6} color="blue.500" />
<chakra(FiUser) boxSize={5} color="green.500" />
<chakra(FiSettings) boxSize={4} color="gray.500" />
</>
)
}
高级用法 #
使用 forwardRef #
jsx
import { chakra, forwardRef } from '@chakra-ui/react'
const Input = forwardRef((props, ref) => {
return (
<chakra.input
ref={ref}
px={4}
py={2}
border="1px solid"
borderColor="gray.200"
borderRadius="md"
_focus={{
borderColor: 'blue.500',
outline: 'none',
}}
{...props}
/>
)
})
使用 shouldForwardProp #
jsx
import { chakra } from '@chakra-ui/react'
const CustomComponent = chakra('div', {
shouldForwardProp: (prop) => {
return !['customProp'].includes(prop)
},
})
使用 themeKey #
jsx
import { chakra } from '@chakra-ui/react'
const Heading = chakra('h2', {
themeKey: 'components.Heading',
})
实用示例 #
创建按钮变体 #
jsx
import { chakra } from '@chakra-ui/react'
const Button = chakra('button', {
baseStyle: {
px: 4,
py: 2,
borderRadius: 'md',
fontWeight: 'medium',
transition: 'all 0.2s',
_focus: {
outline: 'none',
ring: '2px',
ringOffset: '2px',
},
_disabled: {
opacity: 0.5,
cursor: 'not-allowed',
},
},
})
const PrimaryButton = chakra(Button, {
baseStyle: {
bg: 'blue.500',
color: 'white',
_hover: { bg: 'blue.600' },
_active: { bg: 'blue.700' },
},
})
const SecondaryButton = chakra(Button, {
baseStyle: {
bg: 'gray.100',
color: 'gray.800',
_hover: { bg: 'gray.200' },
_active: { bg: 'gray.300' },
},
})
创建布局组件 #
jsx
import { chakra } from '@chakra-ui/react'
export const Container = chakra('div', {
baseStyle: {
w: '100%',
mx: 'auto',
maxW: 'container.lg',
px: 4,
},
})
export const Section = chakra('section', {
baseStyle: {
py: 16,
},
})
export const Grid = chakra('div', {
baseStyle: {
display: 'grid',
gap: 6,
gridTemplateColumns: {
base: '1fr',
md: 'repeat(2, 1fr)',
lg: 'repeat(3, 1fr)',
},
},
})
创建表单组件 #
jsx
import { chakra, forwardRef } from '@chakra-ui/react'
export const FormLabel = chakra('label', {
baseStyle: {
display: 'block',
mb: 2,
fontSize: 'sm',
fontWeight: 'medium',
color: 'gray.700',
},
})
export const FormInput = forwardRef((props, ref) => (
<chakra.input
ref={ref}
w="100%"
px={4}
py={2}
border="1px solid"
borderColor="gray.300"
borderRadius="md"
_placeholder={{ color: 'gray.400' }}
_focus={{
borderColor: 'blue.500',
ring: '2px',
ringColor: 'blue.200',
}}
{...props}
/>
))
export const FormHelper = chakra('p', {
baseStyle: {
mt: 1,
fontSize: 'sm',
color: 'gray.500',
},
})
export const FormError = chakra('p', {
baseStyle: {
mt: 1,
fontSize: 'sm',
color: 'red.500',
},
})
最佳实践 #
1. 命名约定 #
jsx
const StyledButton = chakra('button')
const ChakraLink = chakra(RouterLink)
2. 导出可复用组件 #
jsx
export const Card = chakra('div', {
baseStyle: {
p: 6,
bg: 'white',
borderRadius: 'lg',
shadow: 'md',
},
})
3. 组合使用 #
jsx
import { Box } from '@chakra-ui/react'
import { chakra } from '@chakra-ui/react'
const CustomBox = chakra(Box)
下一步 #
现在你已经掌握了 Chakra Factory,接下来学习 CSS Reset,了解如何统一浏览器默认样式!
最后更新:2026-03-28