21 【styled-components的使用】
1.为什么要用这个
我们都知道,我们从最开始学css的时候,为了避免写的样式影响到另外的地方。所以我们这样来写的。
#userConten .userBtn button{
font-size: 18px;
}
首先给一个元素写了一个唯一id | class,然后在这个里面写对应的样式,就可以避免影响到其它地方的代码。但是,如果项目是多人协作,那就可能存在命名冲突了,所以我们想要一种技术来让整个项目起的类名都是唯一的id。避免样式冲突等问题。所以css in js 就来了。
简单来说CSS-in-JS就是将应用的CSS样式写在JavaScript文件里面,而不是独立为一些.css,.scss或者less之类的文件,这样你就可以在CSS中使用一些属于JS的诸如模块声明,变量定义,函数调用和条件判断等语言特性来提供灵活的可扩展的样式定义
使用这个技术写的库有很多,react中火的是styled-components,vue中css scope也是这个思想,每个组件都有它的scopeId,样式进行绑定,css modules也是同样的。react中css in js为什么火,框架本身就是html css js 写在一个组件混着写,虽然有些违背一些主流说法,但这就是它的特点,毕竟本身就就可以说html in js,再来一个css in js也很正常。
实现这个的库有很多,在react中最火的就是styled-components。
2.简介
styled-components 是作者对于如何增强 React 组件中 CSS 表现这个问题的思考结果 通过聚焦于单个用例,设法优化了开发者的体验和面向终端用户的输出.
Styled Components 的官方网站将其优点归结为:
- Automatic critical CSS:
styled-components
持续跟踪页面上渲染的组件,并自动注入样式。结合使用代码拆分, 可以实现仅加载所需的最少代码。 - 解决了 class name 冲突:
styled-components
为样式生成唯一的 class name,开发者不必再担心 class name 重复、覆盖以及拼写的问题。(CSS Modules
通过哈希编码局部类名实现这一点) - CSS 更容易移除:使用
styled-components
可以很轻松地知道代码中某个 class 在哪儿用到,因为每个样式都有其关联的组件。如果检测到某个组件未使用并且被删除,则其所有的样式也都被删除。 - 简单的动态样式:可以很简单直观的实现根据组件的
props
或者全局主题适配样式,无需手动管理多个 classes。(这一点很赞) - 无痛维护:无需搜索不同的文件来查找影响组件的样式,无论代码多庞大,维护起来都是小菜一碟。
- 自动提供前缀:按照当前标准写 CSS,其余的交给
styled-components
处理。
因为 styled-components
做的只是在 runtime 把 CSS 附加到对应的 HTML 元素或者组件上,它完美地支持所有 CSS。 媒体查询、伪选择器,甚至嵌套都可以工作。但是要注意,styled-components
是 React
下的 CSS-in-JS
的实践,因此下面的所有例子的技术栈都是 React
。
3.安装
安装样式化组件只需要一个命令
npm install --save styled-components
yarn add styled-components
如果使用像 yarn 这样支持 “resolution” package.json 字段的包管理器,还要添加一个与主要版本范围对应的条目。这有助于避免因项目中安装的多个版本的样式化组件而引起的一整类问题。
在package.json
:
{
"resolutions": {
"styled-components": "^5"
}
}
注意
强烈推荐使用 styled-components 的 babel 插件 (当然这不是必须的).它提供了许多益处,比如更清晰的类名,SSR 兼容性,更小的包等等.
如果没有使用模块管理工具或者包管理工具,也可以使用官方托管在 unpkg CDN 上的构建版本.只需在HTML文件底部添加以下<script>
标签:
<script src="https://unpkg.com/styled-components/dist/styled-components.min.js"></script>
添加 styled-components 之后就可以访问全局的 window.styled
变量.
const Component = window.styled.div`
color: red;
`
注意
这用使用方式需要页面在 styled-components script 之前引入 react CDN bundles
VsCode 有一款插件 vscode-styled-components
能识别 styled-components
,并能自动进行 CSS 高亮、补全、纠正等。
4.基本使用
样式化组件利用标记的模板文本来设置组件的样式。
它删除了组件和样式之间的映射。这意味着当你定义你的样式时,你实际上是在创建一个普通的 React 组件,它附加了你的样式。
以下的例子创建了两个简单的附加了样式的组件, 一个Wrapper
和一个Title
:
import styled from 'styled-components'
/*
创建一个Title组件,
将render一个带有样式的h1标签
*/
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`;
/*
创建一个Wrapper组件,
将render一个带有样式的section标签
*/
const Wrapper = styled.section`
padding: 4em;
background: papayawhip;
`;
// 使用 Title and Wrapper 得到下面效果图
render(
<Wrapper>
<Title>
Hello World!
</Title>
</Wrapper>
);
值得注意的是styled-components
创建的组件首字母必须以大写开头。
几乎所有基础的HTML标签styled都支持,比如div
,h1
,span
…
styled.xxx
后面的.xxx
代表的是最终解析后的标签,如果是styled.a
那么解析出来就是a
标签,styled.div
解析出来就是div
标签。
注意
styled-components 会为我们自动创建 CSS 前缀
5.基于props动态实现
我们可以将 props 以插值的方式传递给styled component
,以调整组件样式.
下面这个 Button
组件持有一个可以改变color
的primary
属性. 将其设置为 ture 时,组件的background-color
和color
会交换.
const Button = styled.button`
background: ${props => props.primary ? "palevioletred" : "white"};
color: ${props => props.primary ? "white" : "palevioletred"};
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
`;
render(
<div>
<Button>Normal</Button>
<Button primary>Primary</Button>
</div>
);
对于react开发者来说,这个还是比较香的。有人说用了这个之后,检查元素无法定位元素,其实它本身name是可以展示的,dev开发时候有一个插件配一下即可styled-components: Tooling
6.样式继承
可能我们希望某个经常使用的组件,在特定场景下可以稍微更改其样式.当然我们可以通过 props 传递插值的方式来实现,但是对于某个只需要重载一次的样式来说这样做的成本还是有点高.
创建一个继承其它组件样式的新组件,最简单的方式就是用构造函数styled()
包裹被继承的组件.下面的示例就是通过继承上一节创建的按钮从而实现一些颜色相关样式的扩展: