styled-components
wǎng luò shí huāng 2024-06-19
styled-components
Styled Components常见样式使用技巧
# styled-components
官网:https://styled-components.com/docs/basics
- 基础使用:https://cloud.tencent.com/developer/article/2321761
Styled Components常见样式使用技巧 (opens new window)
// 修改ant组件样式时 import styled from 'styled-components'; import { Button } from 'antd'; export const StyledButton = styled(Button)` // 必须导出 background: #07f; color: #fff; font-size: 14px; border-color: #07f; &.ant-btn-primary { color: red; } `; // 使用:我们可以直接写组件的任何props <StyledButton type="primary">Button2</StyledButton> // type="primary"会传给Button按钮,进而让上面的&.ant-btn-primary样式生效 // 其原理就是在button组件上加上一个他自己的类名,在这个类型名上使用自定义的样式即可 // 注意:修改ant组件库的样式时,这里写了exports 说明这个组件要被导出使用。如果没有导出直接使用的话,非有可能报错。其他用法例如 sytled.div `` 可以直接使用1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
我们可以在styled-components包裹之后的组件上传递自己的css样式这样一来就非常方便使用:
export const StyledCommonButton = styled(Button)` background-color: #f5f5f5; width: 88px; height: 40px; border-radius: 4px; font-weight: 500; color: #000; border-color: #f5f5f5; &:active, &:hover, &:focus { background: #f5f5f5; border-color: #f5f5f5; color: #000; } ${(props: any) => { return props.$style }} `1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21然后我们可以这样使用:自由改变样式以及结合tailwindcss使用
<StyledCommonButton className='w-3' $style={`color:red; & span {color:red !important;}`}>4e56576</StyledCommonButton> // 注意此时 // 1、styled-components 会自动识别$开头的属性为一个变量,不会把这个字符串动作属性写到元素上;而且我们可以按照最平常的less写法去灵活控制样式。甚至连里面的元素(span元素文字颜色呗设置为red)我们也可直接控制样式。 // 2、我们直接可以和tailwindcss结合使用,此时className='w-3'根据tailwindcss规则就会给元素(button)一个12px的宽。1
2
3
4
结合tailwindcss、styled-components、clsx (opens new window)可以说非常强大:(终极解决方案)
参考:
- https://mp.weixin.qq.com/s/glr73rMrwqbVmjm6GNLAzA
- 截图 (opens new window)
- vscode 插件 Tailwind CSS IntelliSense 解决 class 提示问题(利用上面的规则更好)
- https://blog.csdn.net/qq_41614928/article/details/135962738
- https://cloud.tencent.com/developer/article/2321761
- https://mp.weixin.qq.com/s/glr73rMrwqbVmjm6GNLAzA
利用styled-components的attrs属性结合非常强大
import styled from 'styled-components'; import {twMerge} from 'tailwind-merge' import clsx from 'clsx'; export const StyledCommonButton = styled(Button).attrs((props)=>{ const {className,$base=true,$normal=true,$md=true,$primary,$danger,$success,$sm,$lg,...resProps} = props const base = 'rounded-xl border border-transparent font-medium cursor-pointer transition' // type const normal = 'bg-gray-100 hover:bg-gra // size const md = 'text-sm py-2 px-4' // 计算并最终得到所有类名 const computedClassName = twMerge(clsx($base&&base,$normal&&normal, $md&&md, { // 重点一:先使用clsx计算出所有类名,然后使用twMerge去除能引发样式冲突的类名(后面的类名覆盖前面的类名,参考:https://mp.weixin.qq.com/s/glr73rMrwqbVmjm6GNLAzA),让类名达到最简化 // type ['bg-blue-500 text-white hover:bg-blue-600']: $primary, ['bg-red-500 text-white hover:bg-red-600']: $danger, ['bg-green-500 text-white hover:bg-green-600']: $success, // size ['text-xs py-1.5 px-3']: $sm, ['text-lg py-2 px-6']: $lg, [className]: className && true, })) // 非常重要:为了让tailwindcss去解析className生成对应样式,所以我们把class传递进去;否则className不会被解析。 const makeTailedWindCssWork = <div className={computedClassName}></div> return { // 重点二:使用styled-components的attrs函数,劫持属性并计算最终属性,然后返回。 ...resProps, className: computedClassName, } })` // 下面的样式完全可以不要,直接在clsx函数参数里定义即可 background-color:${props=>props.$theme?.bgcolor??'#f5f5f5'}; width: 88px; height: 40px; border-radius: 4px; font-weight: 500; color: ${props=>props.$theme?.bgcolor??'#000'}; border-color: ${props=>props.$theme?.color??'#f5f5f5'}; &:active, &:hover, &:focus { background: ${props=>props.$theme?.color??'#f5f5f5'}; border-color: ${props=>props.$theme?.color??'#f5f5f5'}; color: ${props=>props.$theme?.bgcolor??'#000'}; } ${(props: any) => { // 重点三:让最外出组件可以控制当前组件以及组件内部元素的样式 return props.$style }} ` // 我们调用组件时: <StyledCommonButton $success className='w-3' $style={`&{color:red;} & span {color:red !important;}`} $theme={ color:'blue', bgcolor:'red' }>4e56576</StyledCommonButton> // 此时我们包含的功能有:可以说兼顾定制以及自定义,非常好用 // 1、参数选型:$success(默认为true)、$theme会被传入作为参数去计算样式 // 2、使用tailwindcss:className='w-3'会被上面的`[className]: className && true,`这句话使用,进而tailwindcss生效,代码写得更少更节约编程时间 // 3、自定义样式:$style={`color:red; & span {color:red !important;}`} 这里的值会被传入到重点三的地方,styled-components生效当做样式合并到样式里去。因为有些样式tailwindcss很难用类名写出来。 // 注意:&{color:red;} 的写法,才能让样式在当前元素起作用1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
当我们发现无法通过style-components去修改组件的样式时(无法通过styled-components插入他自己生成的类名时样式就不会生效):
此时我们可以使用
createGlobalStyle方法去处理,生成全局样式// tooltip import styled, { createGlobalStyle } from 'styled-components' const STooltip = ({ overlayClassName = 'ant-tooltip-inner-custom', $style, ...resProps }) => { const StyledTip = styled(Tooltip).attrs((props: any) => { Object.assign(props, { overlayClassName, ...resProps }) return props })`` const GlobalStyle = createGlobalStyle` ${(props: any) => { return overlayClassName == 'ant-tooltip-inner-custom' ? `.ant-tooltip-inner-custom { // 当前css选择器必须和overlayClassName值相等 text-align: center; .ant-tooltip-inner { border-radius: 12px !important; padding: 20px 20px 16px 20px; } .qrcode { display: block; width: 120px; height: 120px; border-radius: 8px; } .smallTip { margin-top: 6px; font-size: 12px; line-height: 18px; color: #666; text-align: center; } }` : $style }} ` return ( <> <GlobalStyle /> <StyledTip></StyledTip> </> ) } // 我们通过给 当前组件一个overlayClassName属性值,以及$style属性值,那么当前组件就可以修改样式 export const StyledTooltip = memo(STooltip)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43