用React刻自己的投资Dashboard Day24 - styled components

tags: 2021铁人赛 React

因为下一篇要让导览列在手机版网页呈现汉堡选单的样式,在参考其他工程师写的网页的时候,发现有一位是用styled-components这个套件来写的,这篇就来了解styled-components的特色,以及学习怎麽使用它。

CSS in JS

就是可以把CSS写在JS里面的意思,这样的写法好处是写在JS里面的CSS设定,只会对这支JS产生的HTML元素有效果,不会影响到别支JS档产生的元素。这跟之前的CSS module有类似的作用,不过styled-components还有许多CSS module没有的特点,下面会再一一说明。
下面这个是CSS in JS的简单范例,也可以到codepen连结玩玩:

const Container = styled.div`
  text-align: center;
`

const Button = styled.button`
  border-radius: 3px;
  border: 2px solid palevioletred;
  color: palevioletred;
  margin: 0 1em;
  padding: 0.25em 1em;
`

function App() {
  return (
    <Container>
      <Button>Normal Button</Button>
    </Container>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('app')
)

Props

可以透过props将变数传递至CSS样式内,官方范例如下,或是可以至codepen玩玩,看到button会出现两种背景不同样式,因为一个有加primary。这个功能我觉得还蛮好用的,可以根据载入JSX元件的资料动态改变CSS设定,例如股票的涨跌就会用到,数字大於0就用红色,数字小於0就用绿色...之类的用法。不过要记得import { css }喔。

const Container = styled.div`
  text-align: center;
`

const Button = styled.button`
  background: transparent;
  border-radius: 3px;
  border: 2px solid palevioletred;
  color: palevioletred;
  margin: 0 1em;
  padding: 0.25em 1em;

  ${props =>
    props.primary &&
    css`
      background: palevioletred;
      color: white;
    `};
`

function App() {
  return (
    <Container>
      <Button>Normal Button</Button>
      <Button primary>Primary Button</Button>
    </Container>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('app')
)

{ css }

前一个范例有import { css },这是CSS的helper,当有常用的css设定,就可以把它写成一个helper,就可以重复使用了,因此可以将上一个范例程序码改成这样,props的部份就变得比较简洁。

const Container = styled.div`
  text-align: center;
`

const Button = styled.button`
  background: transparent;
  border-radius: 3px;
  border: 2px solid palevioletred;
  color: palevioletred;
  margin: 0 1em;
  padding: 0.25em 1em;

  ${props =>
    props.primary && helper
`

const helper = 
    css`
      background: palevioletred;
      color: white;
    `

function App() {
  return (
    <Container>
      <Button>Normal Button</Button>
      <Button primary>Primary Button</Button>
    </Container>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('app')
)

Extending Styles

这个功能是可以用已经写好的styled components去制作新的components,样式会承接之前写好的部分,然後还可以加上新的样式,可以到codepen玩玩。

const Container = styled.div`
  text-align: center;
`

const Button = styled.button`
  background: transparent;
  border-radius: 3px;
  border: 2px solid palevioletred;
  color: palevioletred;
  margin: 0 1em;
  padding: 0.25em 1em;
`

const GreenButton = styled(Button)`
  color: green;
  border-color: green;
`;

function App() {
  return (
    <Container>
      <Button>Normal Button</Button>
      <GreenButton>Primary Button</GreenButton>
    </Container>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('app')
)

Theming

这个功能非常强大,使用方式是透过ThemeProvider这个wrapper component,将主题样式套用在所有在wrapper内的styled-components,而且不管子元件在多深的阶层都能套用到。范例可至codepen玩玩。

const Container = styled.div`
  text-align: center;
`

const Button = styled.button`
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border-radius: 3px;

  /* Color the border and text with theme.main */
  color: ${props => props.theme.main};
  border: 2px solid ${props => props.theme.main};
`;

const Link = styled.a`
  font-size: 1em;
  color: ${props => props.theme.deeper};
`

Button.defaultProps = {
  theme: {
    main: "palevioletred"
  }
}

const theme = {
  main: "mediumseagreen",
  deeper: "palevioletred"
};

function App() {
  return (
    <Container>
      <Button>Normal</Button>
      <ThemeProvider theme={theme}>
        <Button>Themed</Button>
        <Button><Link>Deeper</Link></Button>
      </ThemeProvider>
    </Container>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('app')
)

小结

styled-components是个非常强大的套件,可以使用的功能还蛮多的,今天写的只是其中一小部份,不过这些暂时先足够拿来制作汉堡选单,下一篇就会开始来制作导览列的汉堡选单罗。


<<:  来做一个色码转换器吧!

>>:  [进阶指南] 深入 JSX( Day25 )

6. 来玩终端机

最基本的 问答时间 到底为甚麽要用终端机?可以用最少的容量来做事(图形介面还要读取图片) 是不是打指...

Day 22 - Blocking & Non-blocking Mode

本篇重点 官方说明文件:https://sinotrade.github.io/tutor/adva...

Rust-定义函式Function(二)

函式传递参数 每次调用函式时都打印相同的hello word的函式不是很有用处 这时候可以传递参数给...

Day 15 「一切皆空」单元测试、Code Smell 与重构 - Null 篇

一切皆空,影片来源:YouTube 一般人以为佛教说的空,,等於什麽都没有,是消极并悲观的,其实不...

什麽是 ArchiMate?

ArchiMate 是The Open Group面向企业架构的开放且独立的建模语言,由不同的工具供...