Shu-How Zの小窝

Loading...

前端开发必备-带你了解CSS-IN-JS解决方案的优缺点

前端开发必备-带你了解CSS-IN-JS解决方案的优缺点

https://www.bilibili.com/video/BV1Ss4y1k7hB

P1 01.专题内容介绍

3.Emotion 库

P2 02.为什么会有CSS-IN_JS这种解决方案

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

P3 03.CSS-IN-JS解决方案的优缺点

CSS-IN-JS 方案的优点:
1.让 CSS代码拥有独立的作用域,阻止 CSS代码泄露到组件外部,防止样式冲突.
2.让组件更具可移植性,实现开箱即用,轻松创建松耦合的应用程序3.让组件更具可重用性,只需编写一次即可,可以在任何地方运行.不仅可以在同一应用程序中重用组件,而且可以在使用相同框架构建的其他应用程序中重用组件.
4.让样式具有动态功能,可以将复杂的逻辑应用于样式规则,如果要创建需要动态功能的复杂UI,它是理想的解决方案.

CSS-IN-JS 方案的缺点:
1.为项目增加了额外的复杂性.
2.自动生成的选择器大大降低了代码的可读性

P4 04.babel配置以支持css属性的两种方式

3.1 Emotion 介绍
Emotion 是一个旨在使用 JavaScript 编写 CSS 样式的库.
npm install @emotion/core @emotion/styled

1.JSX Pragma通知 babel,不再需要将 jsx 语法转换为 React.createElement 方法,而是需要转换为 jsx 方法.

/** @jsx jsx */
import { jsx } from "@emotion/core"

function App() {
  return (
      <div css={{width:100,height:100,background:'red'}}></div>
  )
}
export default App

2.Babel Preset
1.npm run eject
2.在 package.json 文件中找到 babel 属性,加入如下内容

"presets":[
    "react-app",
    "@/emotion/babel-preset-css-prop"
]

vite

vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react({
    babel:{
      plugins:[
         "@emotion/babel-plugin"
      ]
    },
    jsxImportSource:"@emotion/react"
  })],
})


function App() {
  return (
      <div css={{width:100,height:100,background:'red'}}></div>
  )
}
export default App


P5 05.css方法的使用方式

3.3 css 方法
1.String Styles

3.3 css 方法
2.Object Styles

import {css} from '@emotion/react'
// import {css} from '@emotion/core' ///create-react-app 写

//推荐
const style=css`
  width:100px;
  height:100px;
  background:blue;
`

// const style=css({
//   width:100,
//   height:100,
//   background:'red'
// })

console.log(style,222)

function App() {
  return (
      <div css={style}></div>
  )
}
export default App

P6 06.emotion中css属性优先级

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

import {css} from '@emotion/react'
// import {css} from '@emotion/core' ///create-react-app 写
import Koo from './Koo'

const style=css`
  background:blue;
`
function App() {
  return (
      <div>
        <Koo css={style}></Koo>
      </div>
  )
}
export default App

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

const style=css`
    width:100px;
    height:100px;
    background:green;
`
export default function Koo(props:any) {
  return (
    <div css={style} {...props}>Koo</div>
  )
}

P7 07.创建样式化组件

3.5 Styled Components 样式化组件样式化组件就是用来构建用户界面的,是 emotion 库提供的另一种为元素添加样式的方式。

import {css} from '@emotion/react' //vite.config.ts 改变名字了
// import {css} from '@emotion/core' ///create-react-app 写
import styled from '@emotion/styled'

const Container=styled.div({
  width:100,
  height:100,
  background:'pink',
  marginTop:200
})

const Button=styled.button`
  width:50px;
  height:25px;
  background:red;
  margin-top:15px;
`

function App() {
  return (
      <div>
        <Container>
          <Button>click</Button>
        </Container>
      </div>
  )
}
export default App

P8 08.样式化组件默认样式的覆盖方式

import {css} from '@emotion/react' //vite.config.ts 改变名字了
// import {css} from '@emotion/core' ///create-react-app 写
import styled from '@emotion/styled'

const Container=styled.div(props=>({
  width:props.w||100,
  height:100,
  background:'pink',
  marginTop:200
}))

const Button=styled.button`
  width:50px;
  height:25px;
  background:${props=>props.bgColor||'red'};
  margin-top:15px;
`

function App() {
  return (
      <div>
        {/* w={200}不带单位 */}
        <Container w="200px">
          <Button bgColor="green">click</Button>
        </Container>
      </div>
  )
}
export default App

P9 09.为任何组件添加样式

import styled from '@emotion/styled'

function Demo({className}){
  return <div className={className}>hello emotion!</div>
}

const NewDemo=styled(Demo)`
  color:blue;
`
const NewDemo2=styled(Demo)({
  background:'yellow'
})

function App() {
  return (
      <div>
        <NewDemo></NewDemo>
        <NewDemo2/>
      </div>
  )
}
export default App

P10 10.为特定父级下的子组件添加样式

import styled from '@emotion/styled'

// const Child=styled.div`
//   color:green;
// `
// const Parent=styled.div`
//   ${Child}{
//     color:red
//   }
// `

const Child=styled.div({
  color:'green'
})
const Parent=styled.div({
  [Child]:{
    color:'red'
  }
})

function App() {
  return (
    <div>
      <Child>hello</Child>
      <Parent><Child>hello</Child></Parent>
    </div>
  )
}
export default App

P11 11.css选择器&

import styled from '@emotion/styled'

const Demo=styled.div`
  width:100px;
  height:100px;
  background:blue;
  &:hover{
    background:red;
  }
`

function App() {
  return (
    <div>
      <Demo/>
    </div>
  )
}
export default App

P12 12.样式化组件属性as的用法

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

import styled from '@emotion/styled'

const Button=styled.button`
  color:green;
`

function App() {
  return (
    <div>
      {/* 变为a标签 */}
      <Button as="a" href="javascript:alert('111')">click</Button>
    </div>
  )
}
export default App

P13 13.样式组合

在样式组合中,后调用的样式优先级高于先调用的样式.

import {css} from '@emotion/react'

const style=css`
  background:red;
`

const style2=css`
  background:blue;
`

function App() {
  return (
    <div css={[style,style2]}>
      hello,emotion
    </div>
  )
}
export default App

P14 14.Global组件

import {css,Global} from '@emotion/react'

const style=css`
  body{
    background:red;
  }
`

function App() {
  return (
    <div>
      <Global styles={style}/>
    </div>
  )
}
export default App

P15 15.使用keyframes方法定义关键帧动画

import {css,keyframes} from '@emotion/react'

const move=keyframes`
  0%{
    background:red;
  }
  100%{
    background:green;
  }
`

const style=css`
  width:100px;
  height:100px;
  animation:${move} 2s ease infinite alternate;
`

function App() {
  return (
    <div css={style}>
    </div>
  )
}
export default App

P16 16.创建主题

1.下载主题模块
npm install emotion-theming

import {css,useTheme} from '@emotion/react'

const style=props=>css`
  background:${props.colors.primary}
`

function App() {
  let theme=useTheme()
  console.log(theme.colors.primary)
  return (
    <div css={style}>
      hello world
    </div>
  )
}
export default App

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import {ThemeProvider} from '@emotion/react'
// import {ThemeProvider} from 'emotion-theming' //webpack

const theme={
  colors:{
    primary:'red'
  }
}

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <ThemeProvider theme={theme}>
      <App />
    </ThemeProvider>
  </React.StrictMode>,
)

posted @ 2024-12-11 20:43  KooTeam  阅读(121)  评论(0)    收藏  举报