2023年重新认识一下Css In JS,更细腻组件开发体验。

163 阅读5分钟

说到Css In Js,不深入了解的人,会人抵制这个理念。也会有一些声音会很抵制他们,起源是因为很多人都受到“教科书版”的思维限制了Css In Js的开发。

今天梦兽编程就来聊聊Css In Js的一些使用心得。说起Css In Js,我们不得不想到styled-components。当然还有另一类细腻的组件开发封装的兴起tailwindcss。它们的出现都是在告诉你你的WEB应该都在这个组件进行(JSX)组件修改,而不是开发一个组件另起炉灶在写一份类似的样式。

现在你要有一个思维就是你强迫你是开发组件,无论你以后的web如何迭代,你都必须使用这个组件,如果未来有什么UI上的样式改动,你应该会想到第一时间去查找的是这个组件的Jsx文件,不会第一时间去翻越你写的那个样式文件。

如果你感觉tailwindcss不好用,一般原因是写的组件不是很细腻,而是吧很多div关系都写到里面。如果写得勾细腻的组件,一个组件不会出现太多的classname。

Rex

在Mui开源库的一些启发。

没深入了解Mui之前,梦兽编程和大多数开发一样也很抵制Css In Js,好不容易分离的生态,为什么又要将其何在一个文件进行开发?

在几次给Mui官方库提交PR后,我发现css in js真的是写细腻组件和定制化的好帮手

Css In Js 并发让你写在一个.js文件里!这种思想是错误的。如果你把它理解成Css In Javascript。那么就是说这个Css可以平垫成Javascript的语言进行开发css。也是说Css In Js的符合React组件开发的产物。在你开发过程中也很容易写出”干净的HTML”的页面。

干净的HTML?

在我们开发过程中,如果你想一个Table组件。那么我感觉100%的可能会写出类似Antd的那种Table组件,当我们需要修改某些不需要的内容的时候需要就需要通过Props进行修改。 但Css In Js提供了另一种解决思路,就是Bootstarp那种传递web开发直接把Html结构拷贝走就能独立运行的解决方案,如果做一个和你之前的业务组件没有任何瓜葛,你又不想去维护那个已经绑定了很多业务的组件进行迭代开发时候你完全可以拷贝一分新的“HTML”结构进行二次开发,无需要当心你改的了什么导致之前的组件出现什么问题。

比如Mui组件中Table代码:

<TableContainer component={Paper}>
      <Table sx={{ minWidth: 650 }} aria-label="simple table">
        <TableHead>
          <TableRow>
            <TableCell>Dessert (100g serving)</TableCell>
            <TableCell align="right">Calories</TableCell>
            <TableCell align="right">Fat&nbsp;(g)</TableCell>
            <TableCell align="right">Carbs&nbsp;(g)</TableCell>
            <TableCell align="right">Protein&nbsp;(g)</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {rows.map((row) => (
            <TableRow
              key={row.name}
              sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
            >
              <TableCell component="th" scope="row">
                {row.name}
              </TableCell>
              <TableCell align="right">{row.calories}</TableCell>
              <TableCell align="right">{row.fat}</TableCell>
              <TableCell align="right">{row.carbs}</TableCell>
              <TableCell align="right">{row.protein}</TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </TableContainer>

如果以上代码,有一些TableRow做了Click事件,别的业务不需要做这个事件。如果按照Antd的那种思路,我们很容易会在Cloumes进行扩展字段是不是需要这个Click的Props。Mui的Css in Js细腻程度就很巧妙的规避了这种问题,当你感觉两个业务已经截然不同的时候,应当基于基础的组件进行一个新的业务组件进行组装。而不是往一个组件里面塞一堆没必要的参数!

在开始css in js之前,请完全抛弃Less的嵌套写法。

比如 https://github.com/ant-design/ant-design/blob/master/components/menu/style/index.tsx

这里面就是典型Less Css写法。Css in js中应当鼓励开发使用Funtion Programming进行开发

这里面的 github.com/ant-design/…

// 这里一段如果使用Css In Js,不是很建议我们出现div或者span这些标签。
const Item: React.FC<ItemProps> = ({ className, index, children, split, style }) => {
  const { latestIndex } = React.useContext<SpaceContextType>(SpaceContext);

  if (children === null || children === undefined) {
    return null;
  }

  return (
    <>
      <div className={className} style={style}>
        {children}
      </div>
      {index < latestIndex && split && <span className={`${className}-split`}>{split}</span>}
    </>
  );
};

使用Css In JS我们如何修改以上的代码呢?

我们会先看到上面的代码有一个div,然后下面的代码是一个判断的span

这个时候我们可以拆成3个组件来写这个需求

我们先定一个一个styles.ts

import { LAYOUT_LEFT_WIDTH } from "@/utils/styles";
import styled from "styled-components";

//... stylelcod
export const SpanItem = styled.div`
`
//... stylelcode
export const SpanItemSplit = styled.span``

回到我们的组件里面进行二次修改

const Item: React.FC<ItemProps> = ({ className, index, children, split, style }) => {
  const { latestIndex } = React.useContext<SpaceContextType>(SpaceContext);

  if (children === null || children === undefined) {
    return null;
  }

  return (
    <>
      <SpanItem className={className} style={style}>
        {children}
      </SpanItem>
      {index < latestIndex && split && <SpanItemSplit>}>{split}</SpanItemSplit>}
    </>
  );
};

这样我们就很容易写出类型HTML的组件,如果以后有SpanItemSplit你其他地方需要用上,把这个样式export一份。因为这里已经变成一个Fp的组件。

具体可以观看这里的组件开发 Mui alert

梦兽编程Blog

梦兽编程倔强号

梦兽编程知乎

梦兽编程bilibili

#梦兽编程倔强号
https://juejin.cn/user/2066737588876983

#梦兽编程知乎
https://www.zhihu.com/people/mo-dong-74

#梦兽编程bilibili
https://space.bilibili.com/106325238?spm_id_from=333.1007.0.0