这是我参与8月更文挑战的第1天,活动详情查看:8月更文挑战
一、前言
我的青训营系列文章只是用来知识归纳笔记技术分享,而不是教学模板,有问题欢迎大家指出。
本人一个小小带专,自上次更新文章后,就一直在准备着关于升学的问题,所以好久没有看代码和技术帖了,差点一度忘了啥是前端。但是!机缘巧合下,我发现了字节安排的前端青训营活动,便抱着试一试的心理去报名了,然后我就进了(狗头)。青训营的课程十分有趣,字节的技术人员们过来上的课,也有给我们布置作业。在这次半学习半回顾的过程中。做一些以前的技术总结和新学到的东西(顺便蹭蹭8月更文(狗头))。
二、正文
在青训营中,要做个东西出来做展示,而在我们组的技术选型中,因为大家的技术栈各有各的不同,所有在选择样式框架时,选择了CSSinJS
框架(好家伙就我一个不会)。
1. 什么是 CSSinJS
字面意思看,其实就是用 JS
来写 CSS
,但是为什么得搞懂没什么呢?
按我理解的意思时,CSSinJS 是专门为了 React 写,其原因是:
- React 对
html
的融合很棒(JSX
)但是对CSS
的融合几乎没有(很差) - 在React中写
CSS
经常出现 样式污染、难以复用、冗余代码等等问题 对于这一现象,导致许多民间大佬起义,为 React封装了一系列的第三方库用于加强css
。
其中一只黑马的野马,便是 styled-components.
2.styled-components 介绍
我认为 styled-components 受欢迎的几个点:
- 会
css
就能写,减少学习成本 - 用
JS
写CSS
,如虎添翼(变量,函数的方法) - 把样式融入到组件中,避免了样式污染,按需加载等问题
(1) 下载
# with npm
npm install --save styled-components
# with yarn
yarn add styled-components
官方建议:
强烈建议(但不是必需)也使用Babel 插件。它提供了许多好处,比如更清晰的类名、服务器端渲染兼容性、更小的包等等。
(2) 使用
在需要使用的组件文件里引入即可:
import styled from "styled-components";
看了看文档,粗糙的用了起来
“样式组件”
import styled from "styled-components";
// 定义样式变量
const applered = "#e74c3c";
// 样式组件创建
// const 样式组件名 = styled.创建的元素 ` // 样式内容 `(模板字符串)
export const C1Button = styled.button `
padding: 12px 24px;
border: 1px solid ${applered};
background: #FFFFFF;
border-radius: 5px;
color: ${applered};
outline: none;
font-size: 14px;
`;
export default class Demo extends Component{
render(){
return (
<div>
// 使用样式组件
<C1Button>Hello world</C1Button>
</div>
)
}
}
得到个红彤彤的 button
想要给 样式组件的元素添加一些属性,需要使用 attr
方法进行:
import styled from "styled-components";
// 使用 attr方法给 input标签添加属性
export const NavSearch = styled.input.attrs({
placeholder: 'search',
type: 'text',
}) `
width: 160px;
height: 38px;
margin-top: 9px;
padding: 0 40px 0 20px;
box-sizing: border-box;
background-color: #eee;
outline: none;
border: none;
border-radius: 19px;
color: #666;
${// 定义伪类或者伪元素可以使用类似 sass 或 less 的方法 }
&::placeholder {
color: #999;
}
&.focused {
width: 240px;
}
得到一个灰色的输入框:
全局样式
想要在 styleld-components
中设置全局样式,需要而外导入 createGlobalStyle
import styled, {createGlobalStyle} from "styled-components";
// 全局样式
export const globleStyle = createGlobalStyle `
*{margin: 0;padding: 0}
`;
export default class Demo extends Component{
render(){
return (
<div>
// 放在组件树的顶部,在渲染时会自动注入全局样式
<globleStyle></globleStyle>
</div>
)
}
}
但是这玩意有点鸡肋,完全可以用 App.css
所代替。
图片导入
对于有的组件需要导入图片的,我们可以将图片通过 import
导入后以变量的形式加入样式组件里。如:
import styled from "styled-components";
// 导入图片
import logo from '../logo.svg';
// 创建 img标签样式组件
export const LogoImg = styled.img.attrs({
src: logo, // 导入图片
alt: "no_img",
}) `
width: 200px;
border: 1px solid blue;
border-radius: 5px;
box-shadow: 5px 5px 5px rgba(0,0,0,.3);
`;
export default class Demo extends Component{
render(){
return (
<div>
<LogoImg></LogoImg>
</div>
)
}
}
得到一个好看的 React 的logo:
样式组件继承
当组件多起来后,要写的样式就多了起来,那么按这么写下去就要费很大的功夫去写了。styled-components
提供了样式组件的继承能力。子标签与父标签为同一个标签,且有着相同的样式,但子标签可以自行进行覆盖或添加。
import styled from "styled-components";
// 创建一个父级 div样式组件
export const parentDiv = styled.div `
padding: 12px;
border-radius: 5px;
color: #4c4c4c;
background: #e74c3c;
`;
// 创建一个子级 div样式组件并继承于 parentDiv
// const 子样式组件 = styled(父级样式组件) ``;
export const childDiv = styled(parentDiv) `
color: green;
background: #f1c40f;
`;
export default class Demo extends Component{
render(){
return (
<div>
<parentDiv>
<p>This is a text on parent div.</p>
<childDiv>
<p>This is a text on child div.</p>
</childDiv>
</parentDiv>
</div>
)
}
}
子级的 div
在保留了父级的 border-radius
和 padding
的同时,覆盖了color
和 background
:
动画
在原生 CSS
中,动画通过 @keyframes
定义,而 styled-components
中提供了 keyframes
功能用于创建动画。
// 导入
import styled ,{keyframes} from "styled-components";
// 创建一个动画
const rotate = keyframes`
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
`;
// 创建一个div样式组件
export const Windmill = styled.div `
display: inline-block;
${ // 将动画添加到组件上 }
animation: ${rotate} 2s linear infinite;
padding: 2rem 1rem;
font-size: 1.2rem;
`
export default class Demo extends Component{
render(){
return (
<div>
<Windmill>< 💅 ></Windmill>
</div>
)
}
}
得到了一个可爱的旋转雪糕:
props 传参
这个我是真没想到,styled-components
支持获取 props
中的值,通过函数获得 props
,通过三元运算符或者获取其值,可以做出一些不同的效果:
// 导入
import styled from "styled-components";
// props 取值
export const Button = styled.button<any> `
padding: 12px 24px;
border-radius: 5px;
${ // 别学我,这样写又累又没效率 }
border: 1px solid ${(props : any) => props.primary ? "blue" : props.danger ? "red" : props.warning ? "orange" : props.info ? "black" : props.success ? "green" : "blue"};
background: ${(props : any) => props.fill ? props.primary ? "blue" : props.danger ? "red" : props.warning ? "orange" : props.info ? "black" : props.success ? "green" : "#c0c0c0" : "white"};
color: ${(props : any) => props.fill ? "white" : props.primary ? "blue" : props.danger ? "red" : props.warning ? "orange" : props.info ? "black" : props.success ? "green" : "blue"};
outline: none;
font-size: 14px;
margin: 6px;
cursor: pointer;
transition: all .2s ease-in-out;
&:hover{
color: ${(props : any) => props.fill ? props.primary ? "blue" : props.danger ? "red" : props.warning ? "orange" : props.info ? "black" : props.success ? "green" : "#c0c0c0" : "white"};
background: ${(props : any) => props.fill ? "white" : props.primary ? "blue" : props.danger ? "red" : props.warning ? "orange" : props.info ? "black" : props.success ? "green" : "blue"};
}
&::after{
content:"";
}
`;
export default class Demo extends Component{
render(){
return (
<div>
<Windmill>< 💅 ></Windmill>
</div>
)
}
}
得到各式各样的按钮:
总结
styled-components
对于React 的 css
来说,不失为一种好选择,但也不是最优解。
说说我认为的 styled-components
的缺点:
- 每种样式的标签绑定一种样式(即使你继承做的很好),需要做出许多的样式组件,不易于查看。
- 对于想做特效或动画、样式变化的情况不是很友好
得出结论:我还是喜欢 sass
最后
有什么问题希望大家可以指明我好及时更正。
我的青训营的文章是作为个人学习笔记的。在开学前在冲刺一下下。
新人上路,还请多多包含。
我是MoonLight,一个初出茅庐的小前端。