react classname多个_为什么我更喜欢使用Styled components来构建React应用

cfd83909a043fca945c8d6c548cb2679.png
作者: Luke Hall 原文:Why I prefer Styled components to build React apps

在我的开发栈系列文章的Part #1中,我说明了为什么我使用React作为主框架的几个理由。现在你可能会想知道……

“这家伙是怎么处理CSS的?”

答案是:

用Styled components简单又轻松

npm install styled-components

你要做只有这些。真的!这就是我为什么喜欢它!不用Babel,不用Webpack,不用CSS前后处理。只有JavaScript,别的不需要。

CSS in JS

“大哥,你意思是在JS里写CSS,这很奇怪,我永远不会这么做!”

但是让我们先来写一些Styled component:

import styled from 'styled-components;

const Title = styled.h1`
  font-size: 18px;
`;

这里的styled变量中包含的函数可以表示所有已知的HTML元素。看起来怪异的h1` `语法其实一个标记模板字面量。它实际上相当于调用了一个函数:h1(' ')

得到的Title组件 和其他的一般React 组件用法相同:

<Title>I'm styled and I know it!</Title>

要注意的是只有React可以使用Styled components。

Props

“等等, 里面的Props是怎么回事?”

这就是它强大的地方。请看:

const Button = styled.button`
  background: ${props => props.primary ? 'green' : 'gray'};
`;

<Button primary>Click me!</Button>

在模板字符串中用箭头函数提供props变量。这样你可以给CSS样式传入任意值。

换句话说,不仅可以传入CSS属性值,还可以这么做:

import styled, { css } from 'styled-components;

const Position = styled.div`
  position: absolute;  ${({ side, value }) => css`
    ${side}: ${value};
  `}
`;

<Position side="right" value="50%">
  I'm positioned!
</Position>

代码片段

“上面的css变量是什么?”

这是一个用于构建CSS代码片段的helper函数。当你需要一些反复出现的CSS时很有用。只需这么做:

const underlineOnHover = css`
  text-decoration: none;  
  :hover {
    text-decoration: underline;
  }
`;

然后将它用在任意你需要的组件中:

const Link = styled.a`
  color: green;
  ${underlineOnHover};
`;

(无需)class

“但是……怎么才能添加classname属性呢?我要改变嵌套在组件中的另一个组件的样式”

忘了class吧!你可以不需要它们了。

只需这么选择被嵌套组件:

const Button = styled.button`
  ${Icon} {
    width: 20px;
  }
`;

在如下两种情况中都可以这么做:

  • Icon是Styled component组件。
  • Icon不是Styled component组件,但想给它里面的元素传入classname属性。例如这里的Icon可以是react-router里的Link组件。

在HTML和CSS之间,定义class不是必须的步骤。

你不必根据props有条件的对组件应用class。只需直接根据props有条件的编写CSS。

别误解我的意思,当然在浏览器渲染后还是使用的class。但那些是动态生成的,你不需关心它们。

它们看起来像这样:

.cAqXJf {
    padding: 10px;
  }

Debugging

“得了吧,那太可怕了!那你怎么在浏览器中debug呢?你不知道这莫名其妙的class是属于哪个组件!”

你是对的,你知不道。还记得我说你不需要为Styled components设置Babel吗?这里是个例外。

这里可以用babel-plugin-styled-components插件。设置好后,你就可以在浏览器里看到可读的class名,像这样:

<div class="ProductList-cAqXJf">...</div>

CSS特性支持

“开始有点意思了。但我打赌我可以发现某些Styled components不能做的事情。你怎么处理伪选择器和伪元素,嗯?”

方法和在普通的CSS里面一样:

const Link = styled.a`
  :hover {
    color: orange;
  }  
  :before {
    content: 'styled components are awesome'
  }
`;

总之,你在CSS里可以做的任何事都可以在Styled components里做。

Media queries, animation keyframes, gradients, transformations……所有东西都是开箱即用的

全局样式

“我想到了!全局样式!我知道我会找到!你不能做到这个!你不可能让<html>或<body>元素成为Styled组件!”

好吧,你不能让<html>成为Styled组件,但是Styled components的作者没有忘记这点。别担心。

你可以很容易在全局使用自定义字体。正如官方文档的例子:

import { injectGlobal } from 'styled-components';injectGlobal`
  @font-face {
    font-family: "Operator Mono";
    src: url("../fonts/Operator-Mono.ttf");
  }

  body {
    margin: 0;
  }
`;

注:injectGlobal现已弃用,更改为createGlobalStyle。

SSR和性能

“你难住我了。那么服务器端渲染怎么样呢?”

这也支持的很好。不用担心用户会在页面载入前看到没有样式的页面。

而且它的优点是,CSS是JS组件的一部分。从性能的角度上看:

  • 你只需用一个包中就载入所有东西
  • 你只载入那些你确实需要的组件的样式

React native

“但我主要是用React Native开发移动应用,所以这东西我用不上……”

没想到吧!Styled components对React Native也支持。别担心。

import styled from 'styled-components'const View = styled.View`
  display: flex;
`;

你甚至可以构建一组平台无关的Styled 组件。然后将它们用在web,IOS,Android的开发中。

主题

“哇,听起来很棒!也许我会在我下一个项目中考虑Styled components”

我再给你一个理由,无疑你应该试试。这是我最喜欢它的地方。

Styled components支持开箱即用的主题:

import styled, { ThemeProvider } from 'styled-components';

const theme = {
    colors: {
      primary: '#4e812b',
      secondary: '#ee921a'
    }
  }
  
const App = props => (
    <ThemeProvider theme={theme}>
      {props.children}
    </ThemeProvider>
);

现在你app内的任意组件都有theme属性了。

const Button = styled.button`
  background: ${({ theme, primary }) => (
    primary ? theme.color.primary : theme.color.secondary
  )};
`;

<Button primary>Click me!</Button>

在app里的所有地方改变颜色变得非常简单,传入primary或secondary即可。

扩展样式

另一个超级有用的特性是可以很容易扩展任意组件的样式。

import styled from 'styled-components';
import Button from './Button';

const DisabledButton = styled(Button)`
  background: gray;
  cursor: not-allowed;
`;

这将把原始组件的样式与新样式合并在一起。

还有更多……

使用Styled components还有更多可能性。请查阅官方文档。

注意事项

在Styled components中有些事情会让你感到奇怪。

嵌套元素

其中一件事是,你不能创建一个返回超过一个HTML子元素的Styled component组件。

Styled component组件 = 单个HTML元素(或React Native中的原生元素)。

解决的办法也很简单,如果你需要一个结构复杂的组件。只需创建一个普通的React组件,它由多个Styled component组件构成:

const Wrapper = styled.div`
  display: flex;
`;
const Left = styled.div`
  flex-grow: 1;
`;
const Right = styled.div`
  flex-grow: 2
`;

const Layout = props => (
  <Wrapper>
    <Left>Left column</Left>
    <Right>Right column</Right>
  </Wrapper>
);

HTML可读性变差

我在上面已经提到过,渲染出来的HTML默认包含随机生成的class名。但babel-plugin-styled-components可以很容易解决这个问题。

编辑器的语法支持

一些编辑器会对模板字面量语法感到困惑。但一般都会有插件支持,有些编辑器默认就支持CSS突出显示和建议。

React only

Styled components只支持React。如果你用其他的JS框架你必须寻找其他CSS方案。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值