React中css使用方案,使用 craco 在 React 18 中引入 Less ,认识styled-components,ES6标签模板字符串

322 阅读1分钟

内联样式的css

image.png

import React, { PureComponent } from "react";
export class App extends PureComponent {
  constructor() {
    super();
    this.state = {
      titleSize: 16,
    };
  }
  render() {
    const { titleSize } = this.state;
    return (
      <div>
        <button onClick={(e) => this.setState({ titleSize: this.state.titleSize + 3 })}>add titleSize</button>
        <p style={{ color: "red", fontSize: `${titleSize}px` }}>I am title</p>
        <p style={{ fontSize: "30px", color: "pink" }}>this is content</p>
      </div>
    );
  }
}
export default App;

普通的css

image.png

import React, { PureComponent } from "react";
import "./style.css";
import Home from "./Home";
export class App extends PureComponent {
  render() {
    return (
      <div>
        <h1>App</h1>
        <div className="header">header</div>
        <div className="body">body</div>
        <div className="footer">footer</div>
        <Home />
      </div>
    );
  }
}
export default App;
.header {
  color: red;
}
.body {
  color: pink;
}
.footer {
  color: blue;
}
import React, { PureComponent } from "react";
export class Home extends PureComponent {
  render() {
    return (
      <div>
        <h1>Home</h1>
        <div className="header">Home-header</div>
        <div className="body">Home-body</div>
        <div className="footer">Home-footer</div>
      </div>
    );
  }
}
export default Home;

样式冲突:

image.png

CSS_Module

image.png image.png 没有冲突:

image.png

import React, { PureComponent } from "react";
import appStyle from "./App.module.css";
import Profile from "./profile/Profile";
import Home from "./home/Home";
export class App extends PureComponent {
  render() {
    return (
      <div>
        <h2 className={appStyle.title}>I am App title</h2>
        <p className={appStyle.content}>I am App content,zm</p>
        <Home />
        <Profile />
      </div>
    );
  }
}
export default App;
.title {
  color: salmon;
}
.content {
  color: aquamarine;
}
import React, { PureComponent } from "react";
import appStyle from "./Home.module.css";
export class Home extends PureComponent {
  render() {
    return (
      <div>
        <h2 className={appStyle.title}>I am Home title</h2>
        <p className={appStyle.content}>I am Home content,zm</p>
      </div>
    );
  }
}
export default Home;
.title {
  color: brown;
}
.content {
  color: chocolate;
}
import React, { PureComponent } from "react";
import appStyle from "./Profile.module.css";
export class Profile extends PureComponent {
  render() {
    return (
      <div>
        <h2 className={appStyle.title}>I am Profile title</h2>
        <p className={appStyle.content}>I am Profile content,zm</p>
      </div>
    );
  }
}
export default Profile;
.title {
  color: antiquewhite;
}
.content {
  color: blueviolet;
}

Less编写方式

craco官网

  • 相关文章
  • npm i -D @craco/craco
  • npm i -D less less-loader
  • npm i craco-less --force
  • 项目根目录创建文件 craco.config.js
const CracoLessPlugin = require("craco-less");

module.exports = {
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            modifyVars: {},
            javascriptEnabled: true,
          },
        },
      },
    },
  ],
};
  • 修改package.json文件scripts
  "scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "react-scripts eject"
  },

代码:

import React, { PureComponent } from "react";
import "./App.less";

export class App extends PureComponent {
  render() {
    return (
      <div>
        <div className="section">
          <div className="title">title</div>
          <div className="content">content</div>
        </div>
      </div>
    );
  }
}
export default App;
@primaryColor: red;
@borderColor: blue;
@content: gold;
.section {
  border: 1px solid @borderColor;
  .title {
    font-size: 30px;
    color: @primaryColor;
  }
  .content {
    font-size: 20px;
    color: @content;
  }
}

image.png

CSS_in_js写法

image.png

ES6标签模板字符串

image.png

image.png

认识styled-components

image.png

image.png

  • 安装依赖

npm i styled-components --force

  • 安装vscode插件 image.png
  • 代码:
import React from "react";
import ReactDOM from "react-dom/client";
import { ThemeProvider } from "styled-components";

// import App from "./01内联样式的css/App";
// import App from "./02普通的css/App";
// import App from "./03CSS_Modules/App";
// import App from "./04Less编写方式/App";

import App from "./05CSS_in_js写法/App";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <ThemeProvider theme={{ color: "purple", size: "46px" }}>
      <App />
    </ThemeProvider>
  </React.StrictMode>
);

const name = "zm";
const age = 21;
// 1.基本模块字符串的使用
const str = `my name is ${name},age is ${age}`;
console.log("str=> ", str);

// 2.标签模板字符串的使用
function foo(...args) {
  console.log(args);
}
foo("dhs", 21, 1.66);
foo`my name is ${name},age is ${age}`;

image.png

import React, { PureComponent } from "react";
import Home from "./home";
import { AppWrapper, SectionWrapper } from "./style";
export class App extends PureComponent {
  constructor() {
    super();
    this.state = {
      size: 30,
      color: "purple",
    };
  }
  render() {
    const { size, color } = this.state;
    return (
      // 样式组件
      <AppWrapper>
        <h2>App</h2>
        <SectionWrapper tcolor={color} size={size}>
          <div className="title">App title</div>
          <p className="content">App content</p>
          <button onClick={(e) => this.setState({ color: "skyblue" })}>change color</button>
        </SectionWrapper>
        <div className="footer">
          <h2>App footer</h2>
        </div>
        <Home />
      </AppWrapper>
    );
  }
}
export default App;
import styled from "styled-components";
import { largeSize, primaryColor } from "./style/variables";

// 1.基本使用
export const AppWrapper = styled.div`
  /* .section {
    border: 1px solid red;
  } */

  .footer {
    border: 1px solid gold;
  }
`;

// 2.子元素单独抽取到一个样式组件
// 3.可以接收外部传入的props
// 4.可以通过attrs给标签模板字符串中提供属性
// 5.从一个单独的文件中引入变量
export const SectionWrapper = styled.div.attrs((props) => ({
  color: props.tcolor || "blue",
}))`
  border: 1px solid red;

  .title {
    /* font-size: 30px; */
    /* 记得加分号; 不要少写px*/
    font-size: ${(props) => props.size}px;
    /* color: blue; */
    /* color: ${(props) => props.color}; */
    color: ${(props) => props.color};

    &:hover {
      background-color: gold;
    }
  }

  .content {
    /* font-size: 20px;
    color: green; */
    font-size: ${largeSize}px;
    color: ${primaryColor};
  }
`;
                                           variables.js
export const largeSize = 30;
export const primaryColor = "gold";
import React, { PureComponent } from "react";
import { HomeWrapper } from "./style";
export class Home extends PureComponent {
  render() {
    return (
      <HomeWrapper>
        <div className="top">
          <h1 className="banner">Home - BannerContent</h1>
        </div>
        <div className="bottom">
          <h2 className="header">商品列表</h2>
          <ul className="product-list">
            <li className="item">商品列表1</li>
            <li className="item">商品列表2</li>
            <li className="item">商品列表3</li>
          </ul>
        </div>
      </HomeWrapper>
    );
  }
}
export default Home;
import styled from "styled-components";

export const HomeWrapper = styled.div`
  margin-top: 5px;
  padding: 15px;
  border: 1px solid pink;
  .top {
    .banner {
      color: red;
    }
  }

  .bottom {
    .header {
      /* import { ThemeProvider } from "styled-components"; */
      /* color: green; */
      /* <ThemeProvider theme={{ color: "purple", size: "46px" }}>
            <App />
        </ThemeProvider> */
      color: ${(props) => props.theme.color};
      font-size: ${(props) => props.theme.size};
    }

    .product-list {
      .item {
        color: blue;
      }
    }
  }
`;
const CracoLessPlugin = require("craco-less");

module.exports = {
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            modifyVars: {},
            javascriptEnabled: true,
          },
        },
      },
    },
  ],
};

  • 目录结构:

image.png

styled高级特性

image.png

import styled from "styled-components";

const ZMButton = styled.button`
  border: 1px solid pink;
  border-radius: 12px;
`;

export const ZMButtonWrapper = styled(ZMButton)`
  background-color: gold;
  color: skyblue;
`;
import { HomeWrapper, ZMButtonWrapper } from "./style";
<ZMButtonWrapper>ZMButton</ZMButtonWrapper>

image.png