资讯专栏INFORMATION COLUMN

五分钟 Styled-components 高级实用技巧

Profeel / 626人阅读

摘要:甚至完美的结合,不仅是从上,还有上。开胃菜用了语法,直接为我们编写样式创建组件。其实组件继承也算是覆盖的一种。如下当任何父级带有都会覆盖的样式。在上面可以看见我们大量使用了作为选择器,而还有另外的技巧。

写在前面的废话

回到2013年,React凭空出世。但是在那时,我们会想,oh shit! 我们好不容易分离了HTML/CSS/JS, 为什么出现了JSX,我们又需要把HTML和JS耦合在一起?React 创造了 HTML in JS. 在React中,我们知道,一切即组件。那既然HTML能在js里写,为什么我们不把CSS也一起写呢?这样不才是一个真正的组件吗?

Styled-components就是为React而生的,它是CSS in JS的下一代解决方案。以往我们想要做到css scope都需要在webpack中各种配置,或者使用js的解决方案。而styled-components你只需要import styled from "styled-components";即可。

甚至React完美的结合,不仅是从TagName上,还有Props上。使我们的代码有更好的语义化,可维护性更强,效率更高。当然我们无需考虑它的学习成本,只要你用过CSS或者SASS都可以立刻上手,因为它本身就是一种超集的存在。

</>复制代码

  1. 接下来,我会逐步的介绍一些这段时间以来,我非常喜欢的独有的特性。
开胃菜

</>复制代码

  1. const Button = styled.button`
  2. background: #abcdef;
  3. border-radius: 3px;
  4. border: none;
  5. color: white;
  6. `;
  7. console.log(Button); //styled component
  8. console.log(new Button()); // react component
  9. export default CustomButton extends React.component {
  10. render() {
  11. return
  12. }
  13. }

</>复制代码

  1. styled-components 用了tagged template语法,直接为我们编写样式创建组件。
继承

styled-components继承样式有两种写法如下

</>复制代码

  1. const Button = styled.button`
  2. background: #abcdef;
  3. border-radius: 3px;
  4. border: none;
  5. color: white;
  6. `;
  7. const OtherButton1 = styled(button)``;
  8. const OtherButton2 = button.extend``; // 老的写法,不推荐,未来会被废弃

写法一的继承,仅仅只会创建不一样的css rule,而第二种写法会复制一遍base component的css rule,然后在添加不一样的进行css 权重覆盖。不推荐

当然,还有一种有趣的“继承” withComponent,我们可以利用withComponent改变渲染的标签

</>复制代码

  1. const Li = styled.li`
  2. color:#abcdef;
  3. `;
  4. const A = Li.withComponent("a"); // 将会渲染a标签

编译后他们会使用不同的className,这对我们想用同个样式,但是不同标签非常有用。

样式覆盖

</>复制代码

  1. 这里所说的样式覆盖,主要是一些交互上的行为(hover, active)覆盖。其实组件继承也算是覆盖的一种。

以往我们的覆盖写法如下:

</>复制代码

  1. const ListItem = styled.li`
  2. padding: 0;
  3. height: 48px;
  4. &.left-item-focus {
  5. .left-link {
  6. background: ${props => props.color};
  7. }
  8. }
  9. &:hover {
  10. .left-icon {
  11. color: #9e9e9e; // 500
  12. }
  13. }
  14. `;

而在styled中,我们可以使用styled-components 组件方式对我们的DOM进行引用,从而覆盖样式,如下

</>复制代码

  1. const Icon = styled.span`
  2. color: red;
  3. `;
  4. const ListItem = styled.li`
  5. &:hover ${Icon} {
  6. color: green;
  7. }
  8. `;

这依旧是我们过去的思路来覆盖样式,只是我们把选择器直接使用styled组件引用罢了。拥有这样的接口,就更加让我们无需去思考需要给组件取什么className或者id,从而达到覆盖样式的做法。然而还有我最喜欢的另外一种写法。

</>复制代码

  1. TIPS:组件的引用必须是styled-components包装后的组件,直接是react的会报错

</>复制代码

  1. const ListItem = styled.li``;
  2. const Icon = styled.span`
  3. color: red;
  4. ${ListItem}:hover & { // & 代表icon组件
  5. color: green;
  6. }
  7. `;

这段代码实现的是一样的功能,只是我们思路转换了一下。可以发现这样的代码更加没有侵入性。更加符合开放封闭原则,当我们不需要这个Icon组件时,直接把这个Icon删除即可,我们不用去父组件里寻找与该组件有关的样式,不容易造成样式污染。突然觉得眼前一亮,有木有!

当然这种“子组件引用父级”的功能,还有更加广泛的引用。你可以选择该DOM任何parent,再对自己进行样式的覆盖。如下:

</>复制代码

  1. const Icon = styled.span`
  2. color: red;
  3. html.ie-8 & {
  4. // fuck ie8
  5. color: blue;
  6. }
  7. body.xxx & {
  8. color: green;
  9. }
  10. `;

当任何父级带有class都会覆盖Icon的样式。这种“子组件引用父级”的功能也是我最喜欢的功能没有之一。

在上面可以看见我们大量使用了&作为选择器,而&还有另外的技巧。

</>复制代码

  1. const Example = styled.li`
  2. color: red;
  3. & {
  4. color:blue;
  5. }
  6. && {
  7. color: green;
  8. }
  9. `;

大家可以猜猜,这最终会渲染成什么?

</>复制代码

最终会编译成如下class,但是我们的一个&就代表一个class权重也就是说我们最后会渲染原谅色,原因是li被作用于了.fmpfVE.fmpfVE样式表。这个功能非常有用,比如在你使用第三方组件想要覆盖它的样式的时候,我们就可以加多个&来提高样式权重,从而覆盖第三方组件的样式

Theme

关于Theme只想说一点,那就是结合第三方组件应该如何传入Theme呢?我们有一个简单的技巧。比如使用了Material-UI,如果我们需要基于它拓展我们自己的组件,并且需要样式。

</>复制代码

  1. const ThemeProvider: React.SFC = ({ themeName, children }) => {
  2. const theme = themes[themeName];
  3. return (
  4. {React.Children.only(children)}
  5. );
  6. };

之后只需要把我们需要调用的组件使用styled-components提供的withTheme包装一下我们的组件来获取我们的theme。

这样既可以在我们的styled-components里取到theme,material里也可以了。

</>复制代码

  1. 以上就是我们所有的技巧了, 看了这么多有意思的黑科技,难道你还不爱上styled-components吗?

个人网站 http://www.meckodo

Github: https://github.com/MeCKodo

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/113854.html

相关文章

  • 分钟 Styled-components 高级实用技巧

    摘要:甚至完美的结合,不仅是从上,还有上。开胃菜用了语法,直接为我们编写样式创建组件。其实组件继承也算是覆盖的一种。如下当任何父级带有都会覆盖的样式。在上面可以看见我们大量使用了作为选择器,而还有另外的技巧。 写在前面的废话 回到2013年,React凭空出世。但是在那时,我们会想,oh shit! 我们好不容易分离了HTML/CSS/JS, 为什么出现了JSX,我们又需要把HTML和JS耦...

    DevYK 评论0 收藏0
  • css还可以这么写?

    摘要:如果我们使用的话,就可以这么写我们要修改主色,只需要将修改为即可。二让我们可以用伪类的写法去合并一些类。比如会编译成可以看到,生成的中并没有任何的变化,那这个做了什么呢其实在通过引用的对象内发生了变化。 作为一个前端,毫无疑问css肯定是最基础的一项技能之一。css是一个标记语言,没有编程语言的诸多特性,比如变量定义,复用,嵌套等,所以相应的开发效率也受到限制。在追求效率和自动化的当下...

    kidsamong 评论0 收藏0
  • css还可以这么写?

    摘要:如果我们使用的话,就可以这么写我们要修改主色,只需要将修改为即可。二让我们可以用伪类的写法去合并一些类。比如会编译成可以看到,生成的中并没有任何的变化,那这个做了什么呢其实在通过引用的对象内发生了变化。 作为一个前端,毫无疑问css肯定是最基础的一项技能之一。css是一个标记语言,没有编程语言的诸多特性,比如变量定义,复用,嵌套等,所以相应的开发效率也受到限制。在追求效率和自动化的当下...

    zhiwei 评论0 收藏0
  • css还可以这么写?

    摘要:如果我们使用的话,就可以这么写我们要修改主色,只需要将修改为即可。二让我们可以用伪类的写法去合并一些类。比如会编译成可以看到,生成的中并没有任何的变化,那这个做了什么呢其实在通过引用的对象内发生了变化。 作为一个前端,毫无疑问css肯定是最基础的一项技能之一。css是一个标记语言,没有编程语言的诸多特性,比如变量定义,复用,嵌套等,所以相应的开发效率也受到限制。在追求效率和自动化的当下...

    RaoMeng 评论0 收藏0
  • React中使用外部样式的3中方式

    摘要:一关于的认识是一种使用编写样式的处理方案。意味着你不需要关心如何检测和删除那些未使用的代码。支持变量和继承你可以使用变量来设置不同的样式,使用这些不同样式时只需要给样式组件传递一个参数即可。 一、关于css-in-js的认识 1、css-in-js是一种使用 js 编写 css 样式的 css 处理方案。它的实现方案有很多,比如styled-components、polished、glam...

    vboy1010 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<