网站地图    收藏   

主页 > 前端 > react >

react之css-in-js解决方案emotion学习

来源:未知    时间:2024-05-11 17:07 作者:小飞侠 阅读:

[导读] Emotion 介绍 Emotion 是⼀个旨在使⽤ JavaScript 编写 CSS 样式的库. npminstall@emotion/core@emotion/styled JSX Pragma通知 babel, 不再需要将 jsx 语法转换为 React.createElement ⽅法, ⽽是需要转换为 jsx ⽅法...


CSS-IN-JS


CSS-IN-JS 是 WEB 项⽬中将 CSS 代码捆绑在 JavaScript 代码中的解决⽅案. 这种⽅案旨在解决 CSS 的局限性, 例如缺乏动态功能, 作⽤域和可移植性.

CSS-IN-JS ⽅案的优点:

  1. 让 CSS 代码拥有独⽴的作⽤域, 阻⽌ CSS 代码泄露到组件外部, 防⽌样式冲突.

  2. 让组件更具可移植性, 实现开箱即⽤, 轻松创建松耦合的应⽤程序

  3.  让组件更具可重⽤性, 只需编写⼀次即可, 可以在任何地⽅运⾏. 不仅可以在同⼀应⽤程序中重⽤组件, ⽽且可以在使 ⽤相同框架构建的其他应⽤程序中重⽤组件.

  4.  让样式具有动态功能, 可以将复杂的逻辑应⽤于样式规则, 如果要创建需要动态功能的复杂UI, 它是理想的解决⽅案.


CSS-IN-JS ⽅案的缺点: 

1. 为项⽬增加了额外的复杂性. 

2. ⾃动⽣成的选择器⼤⼤降低了代码的可读性


Emotion 介绍


Emotion 是⼀个旨在使⽤ JavaScript 编写 CSS 样式的库. 

npm install @emotion/core @emotion/styled
  1. JSX Pragma 通知 babel, 不再需要将 jsx 语法转换为 React.createElement ⽅法, ⽽是需要转换为 jsx ⽅法.


image.png


2 对react配置提取

. Babel Preset
1. npm run eject
2. 在 package.json ⽂件中找到 babel 属性, 加⼊如下内容
"presets": [
"react-app",
"@emotion/babel-preset-css-prop" <--- 追加这段代码 记得需要安装 @emotion/babel-preset-css-prop
]


代码讲解:

1.jpg

  1. 引入emotion方法被css接收

  2. 支持属性上直接操作

  3. 支持模板字符串操作

  4. 支持对象方式操作

// /** @jsx jsx  */ 
import logo from './logo.svg';
import './App.css';
import { css } from '@emotion/react'

// 模板字符串方式编写
const style = css(`
  fontSize: 20px;
  color: black;
  background:skyblue;
  width: 100px;
  height: 100px;
`)
// 对象方式
const style2 = css({
width: 200,
height: 200,
background: 'skyblue'
})

console.log(style, style2)

function App() {
return (
<div className="App">
<div className='div1' css={{ fontSize: '12px', width: '100px', height: 100, background: 'red '}} >
属性描述
<img src={logo} />
</div>
<div className="App-link" css={style}>
模板字符串方式
</div>
<div css={style2}>
对象方式
</div>
</div>
);
}

export default App;


css 属性优先级

props 对象中的 css 属性优先级⾼于组件内部的 css 属性. 在调⽤组件时可以在覆盖组件默认样式.

1 定义一个CssTest组件如下:

import React from 'react';
import { css } from '@emotion/react'

const style = css(`
    width: 200px;
    height: 200px;
    background: pink;
`)

function CssTest(props) {
return <div css={style} {...props} >css</div>
}

export default CssTest

2 在App里面引入

import CssTest from './CssTest'

...
const style2 = css({
width: 200,
height: 200,
background: 'skyblue'
})

<CssTest css={style2} />
...

3 此时外部css就是props,cssTest内部会降props覆盖css,最终结果是蓝色

image.png

Styled Components 样式化组件

样式化组件就是⽤来构建⽤户界⾯的,是 emotion 库提供的另⼀种为元素添加样式的⽅式

Styled Components 样式化组件

创建样式化组件

import styled from '@emotion/styled'

// 创建emotion按钮组件
const Button = styled.button`
    width: 100px;
    height:36px;
    background: blue;
    color:white;
`
...
<Button>emotion-btn</Button>
...

image.png

根据 props 属性覆盖样式

const Button = styled.button`
    width: 100px;
    height:36px;
    background: ${props => props.bgColor || 'blue'};
    color:white;
`

const Contenter = styled.div(props => ({
width: props.w || 200,
height: 200,
background: 'pink'
}))
...
<Contenter w="100px">
<Button bgColor="green">emotion-btn</Button>
</Contenter>
...

样式覆盖第二种写法:

const Contenter = styled.div({
width: 200,
height: 200,
background: 'pink'
}, props => ({
width: props.w,
background: props.bgColor
}))

image.png

为任何组件添加样式

1 定义个普通组件Demo

// demo
const Demo = ({className}) => <div className={className}>Demo</div>
// 模板字符串形式
const DemoEmotion = styled(Demo)`
    color:red;
`
// 对象形式
const DemoEmotion = styled(Demo)({
    color:'red',
})

2 把组件对Demo进行styled,让DemoEmotion接收

...
<DemoEmotion />
...


通过⽗组件设置⼦组件样式

如果组件被父组件包含后可以判断呈现另一种样式

// 模板字符串方式设置
// const DemoChild = styled.div`
//     color: red
// `
// const DemoParent = styled.div`
//     ${DemoChild} {
//         color: green
//     }
// `
//对象方式设置
const DemoChild = styled.div({
color: 'red'
})
const DemoParent = styled.div({
[DemoChild]: {
color: 'green'
}
})
...
<DemoParent> 
<DemoChild>
Demo2
</DemoChild>
</DemoParent>
...

image.png

css选择器

const DemoChild2 = styled.div(`
    color:green;
    &:hover{
        color:pink;
    }
    & > a {
        color: red;
    }

`)
...
<DemoChild2>
DemoChild2
<a href='https://www.zixuephp.com'>aa</a>
</DemoChild2>
...

image.png


as属性标记

as作用是改变内部属性标记的[类型]

要使⽤组件中的样式, 但要更改呈现的元素, 可以使⽤ as 属性.

const DemoBtn2 = styled.button`
    color: green;
`
...
<DemoBtn2 as="a" href="">DemoBtn2</DemoBtn2>
...

image.png


样式组合

在样式组合中, 后调⽤的样式优先级⾼于先调⽤的样式.

const base1 = css`
    color: blue;
`
const danger = css`
    color: green;
`
...
<button css={[base1, danger]}>[base1, danger]</button>
...

image.png

image.png

image.png


全局样式

全局样式类似对全局 body,ul,li等初始化操作

import { css, Global } from '@emotion/react'
...
<Global
styles={{
                body: {
                margin: 0,
                padding: 0,
                background: 'gray'
                }
            }}
/>
...

image.png

image.png


关键帧动画

const move = keyframes(`
    0% {
        background: skyblue;
        left: 0;
        top: 0;
    }
    100% {
        background: tomato;
        left: 200px;
        top: 300px;
    }

`)

const boxStyle = css`
    width: 100px;
    height: 100px;
    position: absolute;
    display: block;
    animation: ${move} 2s ease infinite alternate;
`
...
<div css={boxStyle}>box</div>
...

chrome-capture-2024-4-11 (2).gif


主题

npm install emotion-theming

引入主题

引⼊ ThemeProvider 组件

// 设置主题
const theme = {
colors: {
primary: 'hotpink'
}
}
// 获取主题
const getThemePrimary = props => css`
    color: ${props.colors.primary}
`
...
<ThemeProvider theme={theme}>
<button>主题下的按钮</button>
<div css={getThemePrimary}>asads</div>
</ThemeProvider>
...

image.png

钩子函数获取主题

import {  useTheme } from '@emotion/react'

const CssThemeTest = function() {
const theme = useTheme()
return <div css={{
        color: theme.colors.primary
    }}>
CssThemeTest----------
</div>
}

export default CssThemeTest

image.png

以上就是react之css in js解决方案emotion学习(1)全部内容,感谢大家支持自学php网。

自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

京ICP备14009008号-1@版权所有www.zixuephp.com

网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

添加评论