CodeLife

vuePress-theme-reco yuqing521    2019 - 2021
CodeLife CodeLife

Choose mode

  • dark
  • auto
  • light
主页
分类
  • 日常
  • 后端
  • 基础知识
  • 前端
  • 读书
标签
时间轴
文档
  • vuepress-reco
Github
联系我
  • 关于我
  • CSDN
  • 掘金
author-avatar

yuqing521

27

文章

33

标签

主页
分类
  • 日常
  • 后端
  • 基础知识
  • 前端
  • 读书
标签
时间轴
文档
  • vuepress-reco
Github
联系我
  • 关于我
  • CSDN
  • 掘金
  • CSS 在 React 和 Vue 中的应用

    • Vue 中使用 CSS 方案
      • Vue 自带的Scoped CSS
      • CSS modules
    • React 中使用CSS 方案
      • CSS module
      • CSS-in-JS
    • Atomic CSS 原子化 CSS

    CSS 在 React 和 Vue 中的应用

    vuePress-theme-reco yuqing521    2019 - 2021

    CSS 在 React 和 Vue 中的应用


    yuqing521 2021-02-15 VueReactCSS前端

    image.png

    # CSS 在 React 和 Vue 中的应用

    # Vue 中使用 CSS 方案

    # Vue 自带的Scoped CSS

    加上 scoped 属性的style会自动添加一个唯一的属性 。比如 data-v-0767f757 为组件内 CSS 指定作用域,编译的时候 .isShow 会被编译成类似 .isShow[data-v-0767f757]

    <style lang="css" scoped>  
      .isShow{ 
    			background:red;
      }
    </style>
    
    1
    2
    3
    4
    5

    缺点:.errShow[data-v-0467f817]并不能保证是唯一的,另外在性能上也不是很好

    # CSS modules

    需要同时使用 webpack 的 Vue Loader

    CSS Modules  是一个流行的,用于模块化和组合 CSS 的系统。vue-loader 提供了与 CSS Modules 的一流集成,可以作为模拟 scoped CSS 的替代方案。

    // webpack.config.js
    {
      module: {
        rules: [
          // ... 其它规则省略
          {
            test: /\.css$/,
            use: [
              'vue-style-loader',
              {
                loader: 'css-loader',
                options: {
                  // 开启 CSS Modules
                  modules: true,
                  // 自定义生成的类名
                  localIdentName: '[local]_[hash:base64:8]'
                }
              }
            ]
          }
        ]
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23

    构建步骤中对CSS类名选择器限定作用域的一种方式(通过hash实现类似于命名空间的方法)。类名是动态生成的,唯一的,并准确对应到源文件中的各个类的样式

    <template>
      <p :class="$style.red">
        This should be red
      </p>
    </template>
    <style module>
    .red {
      color: red;
    }
    .bold {
      font-weight: bold;
    }
    </style>
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    用法

    1. 在style标签中添加module属性,表示打开CSS-loader的模块模式。
    2. 在模板中使用动态类绑定:class,并在类名前面加上'$style.'。
    3. 如果类名包含中划线,则使用中括号语法$style['header-tit'] 也可以使用数组或对象语法。

    # React 中使用CSS 方案

    # CSS module

    CSS Modules 通过webpack配置引入项目,不依赖于任何框架,只要使用webpack配置后就可以用于React/Vue/Angular/jQuery 项目中.

    1. 在webpack.config.js的module中添加如下配置:
    module.exports = {
      entry: __dirname + '/index.js',
      output: {
        publicPath: '/',
        filename: './bundle.js'
      },
      module: {
        rules:[
      {
        test:/.css$/,
        use:[
          {loader:'style-loader'},
          {loader:'css-loader',
            option:{modules:true,localIdentName:'[path][name]__[local]-[hase:base64:5]'}
            ]
      }
    ]
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    上面代码中,关键的是在css-loader的option里配置option:{modules:true},表示打开 CSS Modules 功能。

    /* components/submit-button.js */
    import React, { Component } from 'react';
    import classNames from 'classnames';
    // 重点
    import styles from './submit-button.css';
    
    export default class SubmitButton extends Component {
    render () {
      let text = this.props.store.submissionInProgress ? 'Processing...' : 'Submit';
      let className = classNames({
        [`${styles.base}`]: true,
        [`${styles.inProgress}`]: this.props.store.submissionInProgress,
        [`${styles.error}`]: this.props.store.errorOccurred,
        [`${styles.disabled}`]: this.props.form.valid,
      });
      return <button className={className}>{text}</button>;
    }
    };
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    详细查看:https://github.com/jd-smart-fe/shared/issues/11

    # CSS-in-JS

    以 styled components 方案为例

    安装

    npm install --save styled-components
    
    1

    使用

    import styled from 'styled-components';
    
    export default class SubmitButton extends Component {
    // 给标签加样式
    const Button = styled.button`
      color: palevioletred;
      font-size: 1em;
      margin: 1em;
      padding: 0.25em 1em;
      border: 2px solid palevioletred;
      border-radius: 3px;
    `;
    
    // 给组件加样式,覆盖原来的部分样式
    const TomatoButton = styled(Button)`
      color: tomato;
      border-color: tomato;
    `;
    render(){
      return (
        <div>
          <Button>Normal Button</Button>
          <TomatoButton>Tomato Button</TomatoButton>
        </div>
    )};
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26

    # Atomic CSS 原子化 CSS

    原子 CSS 就像是实用工具优先(utility-first)CSS 的一个极端版本: 所有 CSS 类都有一个唯一的 CSS 规则。

    /* 原子 CSS */
    .bw-2x {
      border-width: 2px;
    }
    .bss {
      border-style: solid;
    }
    .sans {
      font-style: sans-serif;
    }
    .p-1x {
      padding: 10px;
    }
    /* 不是原子 CSS 因为这个类包含了两个规则 */
    .p-1x-sans {
      padding: 10px;
      font-style: sans-serif;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    Tailwind 使用的方法是非常便捷的,并且解决了上述一些问题。

    以 Tailwindcss 为例它通过 Utility-First 的理念来解决 CSS 的一些缺点,通过抽象出一组类名 -> 原子功能的集合,来避免你为每个 div 都写一个专有的 class,然后整个网站重复写很多重复的样式。

    它提供了一些公用的命名约定。通过一个配置文件,你可以为你的网站生成一套专属的实用工具 CSS

    // tailwind.config.js
    module.exports = {
      theme: {
        screens: {
          'sm': '640px',
          // => @media (min-width: 640px) { ... }
    
          'md': '768px',
          // => @media (min-width: 768px) { ... }
    
          'lg': '1024px',
          // => @media (min-width: 1024px) { ... }
    
          'xl': '1280px',
          // => @media (min-width: 1280px) { ... }
        }
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    详细查看:https://juejin.cn/post/6917073600474415117