React项目 - 几种CSS实践

小编 2026-06-06 阅读:1449 评论:0
前言团队在使用react时,不断探索,使用了很多不同的css实现方式,此篇blog总结了,react项目中常见的几种css解决方案:inline-style/radium/style-comp...

前言
团队在使用react时,不断探索,使用了很多不同的css实现方式,此篇blog总结了,react项目中常见的几种css解决方案:inline-style/radium/style-component,只列举了团队项目中用过的一下实现方式,还有其他的不过多展开

css的不足
样式与状态相关的情况越来越多,需要动态、能直接访问组件state的css。
一切样式都是全局,产生的各种命名的痛苦,BEM等命名规则能解决一部分问题,但当你使用三方插件时却无法避免命名冲突。

Vue怎么解决
scoped 属性
动态css的语法 v-bind class style

react中使用css的标准
是否解决了React开发的痛点:局部css,动态css?
是否支持所有css甚至是sass用法?伪类,嵌套,动画,媒体查询?
是否兼容你需要使用的第三方UI库?
是否能和纯css,或者是其他css框架很好共存,以备遇到特殊情况可以有方案B?
性能?大小?

react 原生css
inline style


const textStyles = {
  color: \'white\',
  backgroundColor: this.state.bgColor
};

<p style={textStyles}>inline style</p>

缺点:


发明了一套新的 css-in-js 语法,使用驼峰化名称等一些规则
不支持所有的 css,例如 media queries, browser states (:hover, :focus, :active) and modifiers (no more .btn-primary!).
inline 写法如果直接同行写影响代码阅读,不清晰优雅

Radium
Features:
Conceptually simple extension of normal inline styles 原生css扩展,改良版
Browser state styles to support :hover, :focus, and :active 支持浏览器样式
Media queries 支持媒体查询
Automatic vendor prefixing 自动组件前缀 scope
Keyframes animation helper 写动画更方便,封装Keyframes
ES6 class and createClass support 支持react类和createClass的写法

简单使用:


<Button kind=\"primary\">Radium Button</Button>

import Radium from \'radium\';
import React from \'react\';
import color from \'color\';

class Button extends React.Component {
  static propTypes = {
    kind: PropTypes.oneOf([\'primary\', \'warning\']).isRequired
  };

  render() {
    return (
      <button
        // 多个样式使用数组方便合并
        style={[
          styles.base,
          styles[this.props.kind]
        ]}>
        {this.props.children}
      </button>
    );
  }
}

// 使用了HOC的方式注入样式
// Radium\'s primary job is to apply interactive or media query styles, but even // if you are not using any special styles, the higher order component will still:

// Merge arrays of styles passed as the style attribute
// Automatically vendor prefix the style object
// Radium(config)(component) 还可以传入一些配置
Button = Radium(Button);

var styles = {
  base: {
    color: \'#fff\',
    \':hover\': {
      background: color(\'#0074d9\').lighten(0.2).hexString()
    }
  },

  primary: {
    background: \'#0074D9\'
  },

  warning: {
    background: \'#FF4136\'
  }
};

keyframes使用


class Spinner extends React.Component {
  render () {
    return (
      <div>
        <div style={styles.inner} />
      </div>
    );
  }
}

Spinner = Radium(Spinner);

var pulseKeyframes = Radium.keyframes({
  \'0%\': {width: \'10%\'},
  \'50%\': {width: \'50%\'},
  \'100%\': {width: \'10%\'},
}, \'pulse\');

var styles = {
  inner: {
    // Use a placeholder animation name in `animation`
    animation: \'x 3s ease 0s infinite\',
    // Assign the result of `keyframes` to `animationName`
    animationName: pulseKeyframes,
    background: \'blue\',
    height: \'4px\',
    margin: \'0 auto\',
  }
};

Css Modules
适用于所有使用 webpack 等打包工具的开发环境


{
  loader: \"css-loader\",
  options: {
    importLoaders: 1,
    modules: true,
    localIdentName: \"[name]__[local]___[hash:base64:5]\"  // 为了生成类名不是纯随机
  },
},

import styles from \'./table.css\';

    render () {
        return <div className={styles.table}>
            <div className={styles.row}>
                <div className={styles.cell}>A0</div>
                <div className={styles.cell}>B0</div>
            </div>
        </div>;
    }

/* table.css */
.table {}
.row {}
.cell {}

缺点:


class名必须是驼峰形式,否则不能正常在js里使用 styles.table 来引用
由于css模块化是默认,当你希望使用正常的全局css时,需要通过:local 和 :global 切换,不方便
所有的 className 都必须使用 {style.className} 的形式
写在外部样式文件中,无法处理动态css

优化:


 babel-plugin-react-css-modules
 可以照常写 \'table-size\' 之类带横杠的类名
 正常书写字符串类名,不用加style前缀


// .bablerc
{
  \"plugins\": [
    [\"react-css-modules\", {
      // options
    }]
  ]
}

缺点:


不过使用 styleName 遇到三方UI库该怎么办呢

补充:
create-react-app v2 直接使用css-moudues和sass
使用方法为一律将css文件命名为 XXX.modules.css, 以上例,即为 table.modules.css, 即可使用。这一解决法的优雅在于,全局的css可以正常使用,只有带.modules.css后缀的才会被modules化

styled-components
使用 ES6 的模板字符串,在js文件里写纯粹的css。

补充sass常用语法

变量:以$开头/变量需要在字符串之中,在#{}之中
计算: 属性可以使用算式
嵌套: &引用父元素
继承: @extend
重用: @mixin命令,定义一个代码块(可以传参数)/@include命令,调用这个mixin
引入文件: @import


// 变量
    $blue : #1875e7;
    $side : left;
    div {
      color : $blue;
    }
    .rounded {
       border-#{$side}-radius: 5px;
    }

// 计算
   body {
    margin: (14px/2);
    top: 50px + 100px;
    right: $var * 10%;
  }

// 嵌套
   a {
    &:hover { color: #ffb3ff; }
  }

// 继承
    .class1 {
    border: 1px solid #ddd;
  }
    .class2 {
    @extend .class1;
    font-size:120%;
  }

// 重用
    @mixin left($value: 10px) {
    float: left;
    margin-right: $value;
  }
    div {
    @include left(20px);
  }

//引入外部文件
    @import \"path/filename.scss\"

来源:https://segmentfault.com/a/1190000016952542

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表