關於React 中All in js的淺嘗輒止(React 柱狀圖,環形圖)

什麼是 All in js

前段時間在別人的項目上了解到了styled-components插件,它能夠用js來寫css,方便的在其中加上需要的邏輯。React本身用過jsx已經把html用js來寫了,再加上styled-components,就能夠實現All in js 這種編碼方式。

如何看待All in js

瞭解之後跟小夥伴在羣裏討論了一下,這種All in js的方式比較有爭議,不僅在我們的討論中,在整個前端社區裏也是如此。部分人認爲“能用js來做的,必將用js來做”,而且確實在css中直接寫js邏輯有吸引人的地方。另一方面像我這種剛瞭解的人,認爲他上手不夠平滑,寫起來費勁,同時其實大部分css是不需要邏輯的。在與其他人的討論中也發現了一些其他缺點,比如增加了不少成本,新手不夠友好、全局樣式覆蓋成本高漲、僞類處理複雜、與AntD等組件庫結合有坑等。

與此同時 Sass/Less 社區也在飛速發展,尤其是 Stylelint 的成熟,可以通過技術約束的手段來避免 CSS 的 Bad Parts。所以在掘金看到的一篇文章中也號召大家迴歸 Sass/Less ,可見社區也逐漸拋棄了All in js的做法。但作爲一種極客範兒的嘗試,淺嘗輒止的去了解一下還是有點意思的,這裏就簡單放一些我嘗試過的代碼。

styled-components用例

這裏使用styled-components來寫了個環形圖表組件,來展示百分比數據

import React, { PureComponent } from "react";
import styled from "styled-components";
import PropTypes from "prop-types";

// CircleComponment組件的html結構
const CircleComponment = ({ className, precent }) => (
  <div className={className}>
    <div className="precent" />
    <div className="text">
      <strong>{precent}</strong>
      <span>%</span>
    </div>
  </div>
);

// 使用styled-components的styled方法來給CircleComponment組件增加樣式後生成一個新的Circle組件
// 由於要使用css動態表現百分比,所以這裏的css是需要一些邏輯和計算的,很適合使用styled-components來做
// 但可以看到的是,也寫了很多不需要邏輯的純css,都混到一起之後,顯得很長,對閱讀不利。
const Circle = styled(CircleComponment)`
  width: 110px;
  height: 110px;
  float: left;
  position: relative;
  line-height: 100px;
  text-align: center;
  margin: 0 20px;
  &::before {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    border: 10px solid #999;
    border-radius: 50%;
    z-index: 1;
  }
  &::after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    border: 10px solid #38fcc2;
    border-radius: 50%;
    clip: rect(0, auto, auto, 50px);
    z-index: 2;
  }
  .precent {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    border: 10px solid
      ${props => {
        const precent = props.precent;
        let color = "";
        if (precent >= 0 && precent <= 50) {
          color = "#999";
        } else if (precent > 50 && precent <= 100) {
          color = "#38fcc2";
        }
        return color;
      }};
    transform: rotate(
      ${props => {
        const precent = props.precent;
        let deg = 0;
        if (precent >= 0 && precent <= 50) {
          deg = precent * 3.6;
        } else if (precent > 50 && precent <= 100) {
          deg = (precent - 50) * 3.6;
        }
        return `${deg}deg`;
      }}
    );
    border-radius: 50%;
    clip: rect(0, auto, auto, 50px);
    z-index: 3;
  }
  .text {
    color: rgba(255, 255, 255, 1);
    font-size: 30px;
    font-family: Futura-Medium;
    line-height: 110px;
  }
`;

/**
 * CircleGraph用於環形圖表
 */
export default class CircleGraph extends PureComponent {
  static propTypes = {
    precent: PropTypes.string, // 百分比數值
  };

  render() {
    const { precent } = this.props;
    return <Circle precent={precent} />;
  }
}


// 使用時
<CircleGraph precent="30" />
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章