IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> react中每个组件样式独立,避免写className重名而导致污染,类似vue中scope(styled-components的使用) -> 正文阅读

[JavaScript知识库]react中每个组件样式独立,避免写className重名而导致污染,类似vue中scope(styled-components的使用)

前言

在多人开发的时候,或者说二开的时候,不知道大家有没有这样一种体会:

  • 我明明给一个组件添加className了,居然样式不生效?!仔细一看,我靠,原来是别人写的样式影响了我的这个组件的样式,或者说他正好className和我一样,改他的样式吧,又怕影响他,改我的样式吧,又烦,而且别人下次写样式,也有可能会受我的这个影响。
  • 每次我创一个组件,就要另外新建一个.css文件,而且样式又不是很多,但偏偏要新建一个文件,就很烦,而且还要自己想一个className,我懒!直接写在组件上吧,多起来了又显得代码不整洁。
  • 如果组件的样式是动态的,需要根据别人传的props来决定,那我又要面临事先写好两套样式,想两个className
  • 既然react里面支持jsx语法,那我就相当于可以把html代码写在js文件,那为什么就不能在js文件里面写css代码?如果支持的话,不说一定很爽,但至少也可以带来不一样的体验

Tip: 这个时候可能会有人会想到用sass + css module的方案来解决上面的一些问题和疑问,但你都来看这篇文章了,想必你想寻找更好的解决办法,或者说css module也没想到,那这个可以看下阮一峰大佬的文章

正片

在项目中,往往会这样给一个组件加样式:

// App.js
import "./App.css"

function App() {
  return (
    <div className="app">
      <p>
        hello world
      </p>
    </div>
  );
}
/* App.css */
.app p{
    background-color: burlywood;
    font-size: 24px;
}

效果:
在这里插入图片描述
但是现在这里要介绍一种css in js库-----styled-components,先下载:

npm i styled-components -D

常规用法

然后我们就能将上面的常规步骤写成如下这样:

import styled from "styled-components";

const Div = styled.div`
  padding: 6px;
  p{
    background-color: burlywood;
    font-size: 24px;
  }
`

function App() {
  return (
    <Div>
      <p>
        hello world
      </p>
    </Div>
  );
}

效果:
在这里插入图片描述
这时你就会发现两个写法不一样,但是却能达到同样的效果,而且这个新的写法你会发现,其实就是给这个元素加上一个唯一的className,但是不是你自己加啊,它不仅可以可以应用于外层的div元素的padding样式,它还能同时在里面写上后代元素p标签,且样式也是能生效的,甚至你还可以嵌入其他className伪元素sass写法等等,就像下面这样写:

import styled from "styled-components";

const Div = styled.div`
  padding: 6px;
  p{
    background-color: burlywood;
    font-size: 24px;
  }
  .test{xxx: xxx}

  &:hover{
    background-color: antiquewhite;
  }
  
`

function App() {
  return (
    <Div>
      <p>
        hello world
      </p>
    </Div>
  );
}

通过props来决定样式

import styled from "styled-components";

const Div = styled.div`
  width: 100px;
  padding: 5px;
  margin: 10px;
  text-align: center;
  border: 2px solid pink;
  background-color: ${(props) => {
    console.log(props);
    return props.type === 'primary' ? '#3498db' : 'white'
  }};
`


function App() {
  return (
    <>
      <Div >
        default
      </Div>

      <Div type='primary'>
        primary
      </Div>
    </>
  );
}

效果:
在这里插入图片描述
这个时候你就会发现我是通过divtype属性来决定它的背景色,且确实能够在你写css中使用js语法,通过${}的形式传入一个回调函数,回调函数中props对象里面,包括你自己加的type属性,以及自己自带的theme属性,如下:
在这里插入图片描述
在这里插入图片描述
而其中的children属性其实是react它自己会给组件加一个children属性,来代表子元素;theme属性是用来给你传入不同的主题对象,也许为了type不同,你可以直接应用于不同的主题,这里就不过多解释了。

控制组件的其他属性

有些元素本身是具备一些特有的属性的,如inputtype属性,buttononclick属性,你可以这样写:

import styled from "styled-components";

const Input = styled.input.attrs({
  type: 'text'
})``

const Password = styled.input.attrs({
  type: 'password'
})``

const Button = styled.button.attrs({
  onClick: () => {
    console.log('按钮被点击了...');
  }
})``


function App() {
  return (
    <>
      <Input />
      <br />
      <Password />
      <br />
      <Button>按钮</Button>
    </>
  );
}

在这里插入图片描述
在这里插入图片描述
也确确实实可以控制元素本身的一些属性

css混入(mixin、变量化)

import styled, { css } from "styled-components";

const complexMixin = css`
  color: ${props => (props.redColor ? 'red' : 'black')};
`

const StyledComp = styled.div`
  ${props => (props.complex ? complexMixin : 'color: blue;')};
`


function App() {
  return (
    <>
      <StyledComp>
        无complex
      </StyledComp>

      <StyledComp complex redColor>
        有complex 且 redColor
      </StyledComp>
    </>
  );
}

效果:
在这里插入图片描述

keyframes变量化

import { keyframes } from 'styled-components';
const fadeIn = keyframes`
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
`;

const FadeInButton = styled.button`
  animation: 1s ${fadeIn} ease-out;
`;

总结

当然我上面讲诉的是一些比较常用的用法,更多的你可以看下官网文档,不过看了那么多例子,想必也会有些体会:
优点:

  1. 它能让你组件拥有一个唯一的className,不同文件的之间的组件不会受到彼此之间的影响
  2. 它能让你的css支持js语法,从而更加的灵活,而且还能让你同时享受sass写法
  3. 如果你现在就想使用,直接下载依赖包就可以了,不用担心之前的写法不兼容,友好升级

那有没有缺点呢?
我自己体会到的,不知道算不算是缺点:

  1. 虽然可以不用再专门创建一个css文件了,但是如果组件多了,那我这个js文件岂不是越来越大?,越写越多?那后面维护,岂不是很难受?
  2. 我已经习惯于把jscss分开写的习惯了,且react中jsx里面本来也可以直接在组件上面写样式
  3. 如果这个项目是自己一个人写,用这种可能是挺方便的,人多了,是不是还不如用css module
  4. 本质上它是在js运行时,通过webpack的一些loaderheader标签里面插入style标签,这无疑会增加js文件的加载效率
  5. 如果不能把css抽离出去,那岂不是不能享受缓存?

总之看个人和项目吧,这篇文章也仅是学习和记录

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-20 18:43:07  更:2022-07-20 18:44:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 13:00:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码