欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 资讯 > React(六)React过渡动画-CSS编写方式

React(六)React过渡动画-CSS编写方式

2025/5/6 21:51:14 来源:https://blog.csdn.net/weixin_62831076/article/details/146533897  浏览:    关键词:React(六)React过渡动画-CSS编写方式

React过渡动画

react-transition-group介绍

  • 在开发中,我们想要给一个组件的显示和消失添加某种过渡动画,提高用户体验→可通过react-transition-group实现。
  • React曾为开发者提供过动画插件 react-addons-css-transition-group,后由社区维护,形成了现在的 react-transitiongroup。
  • 该组件帮助我们实现组件的入场和离场动画。
  • 安装方式:
# npm
npm install react-transition-group --save
# yarn
yarn add react-transition-group

react-transition-group主要组件

该插件主要包含四个组件:

Transition:基础组件,用于管理单个组件的进入和退出动画

CSSTransition:基于 <Transition> 的高级组件,它通过添加 CSS 类名来实现动画效果

SwitchTransition:两个组件显示和隐藏切换时,使用该组件

TransitionGroup:将多个动画组件包裹在其中,一般用于列表中元素的动画;

CSSTransition

  1. 执行过程中的三个状态:appear、enter、exit
  2. 三种状态对应的CSS样式:
  • 开始状态:xxx-appear、xxx-enter、xxx-exit
  • 执行动画:xxx-appear-active、xxx-enter-active、xxx-exit-active;
  • 执行结束:xxx-appear-done、xxx-enter-done、xxx-exit-done;

3.in:触发进入或者退出状态

  • 当in为true时,触发进入状态,会添加-enter、-enter-acitve的class开始执行动画,当动画执行结束后,会移除两个class, 并且添加-enter-done的class;
  • 当in为false时,触发退出状态,,会添加-exit、-exit-active的class开始执行动画,当动画执行结束后,会移除两个class,并且添加-enter-done的class;

App.jsx 

import React, { createRef, PureComponent } from 'react'
import { CSSTransition } from "react-transition-group"
import "./style.css"export class App extends PureComponent {constructor(props) {super(props)this.state = {isShow: true}this.sectionRef = createRef()}render() {const { isShow } = this.statereturn (<div><button onClick={e => this.setState({isShow: !isShow})}>切换</button>{/* { isShow && <h2>哈哈哈</h2> } */}<CSSTransition nodeRef={this.sectionRef}in={isShow} unmountOnExit={true} classNames="why" timeout={2000}appearonEnter={e => console.log("开始进入动画")}onEntering={e => console.log("执行进入动画")}onEntered={e => console.log("执行进入结束")}onExit={e => console.log("开始离开动画")}onExiting={e => console.log("执行离开动画")}onExited={e => console.log("执行离开结束")}><div className='section' ref={this.sectionRef}><h2>哈哈哈</h2><p>我是内容, 哈哈哈</p></div></CSSTransition></div>)}
}export default App

style.css 

/* 进入动画 */
/* .why-appear {transform: translateX(-150px);
}.why-appear-active {transform: translateX(0);transition: transform 2s ease;
} */.why-appear, .why-enter {opacity: 0;
}.why-appear-active, .why-enter-active {opacity: 1;transition: opacity 2s ease;
}/* 离开动画 */
.why-exit {opacity: 1;
}.why-exit-active {opacity: 0;transition: opacity 2s ease;
}

SwitchTransition

1.核心属性:mode

  • in-out:表示新组件先进入,旧组件再移除;
  • out-in:表示就组件先移除,新组建再进入;

2.子组件必须是 CSSTransition 或 Transition

3.通过 key 属性来区分不同的子组件

App.jsx

import React, { PureComponent } from 'react'
import { SwitchTransition, CSSTransition } from 'react-transition-group'
import "./style.css"export class App extends PureComponent {constructor() {super() this.state = {isLogin: true}}render() {const { isLogin } = this.statereturn (<div><SwitchTransition mode='out-in'><CSSTransitionkey={isLogin ? "exit": "login"}classNames="login"timeout={1000}><button onClick={e => this.setState({ isLogin: !isLogin })}>{ isLogin ? "退出": "登录" }</button></CSSTransition></SwitchTransition></div>)}
}export default App

style.css 

.login-enter {transform: translateX(100px);opacity: 0;
}.login-enter-active {transform: translateX(0);opacity: 1;transition: all 1s ease;
}.login-exit {transform: translateX(0);opacity: 1;
}.login-exit-active {transform: translateX(-100px);opacity: 0;transition: all 1s ease;
}

TransitionGroup

可同时管理多个 TransitionCSSTransition 组件

App.jsx

import React, { PureComponent } from 'react'
import { TransitionGroup, CSSTransition } from "react-transition-group"
import "./style.css"export class App extends PureComponent {constructor() {super()this.state = {books: [{ id: 111, name: "你不知道JS", price: 99 },{ id: 222, name: "JS高级程序设计", price: 88 },{ id: 333, name: "Vuejs高级设计", price: 77 },]}}addNewBook() {const books = [...this.state.books]books.push({ id: new Date().getTime(), name: "React高级程序设计", price: 99 })this.setState({ books })}removeBook(index) {const books = [...this.state.books]books.splice(index, 1)this.setState({ books })}render() {const { books } = this.statereturn (<div><h2>书籍列表:</h2><TransitionGroup component="ul">{books.map((item, index) => {return (<CSSTransition key={item.id} classNames="book" timeout={1000}><li><span>{item.name}-{item.price}</span><button onClick={e => this.removeBook(index)}>删除</button></li></CSSTransition>)})}</TransitionGroup><button onClick={e => this.addNewBook()}>添加新书籍</button></div>)}
}export default App

style.css 

.book-enter {transform: translateX(150px);opacity: 0;
}.book-enter-active {transform: translateX(0);opacity: 1;transition: all 1s ease;
}.book-exit {transform: translateX(0);opacity: 1;
}.book-exit-active {transform: translateX(150px);opacity: 0;transition: all 1s ease;
}

React编写CSS方式

内联样式style

写在行内,传入一个小驼峰命名的js对象,并且可以设置动态的样式

import React, { PureComponent } from 'react'export class App extends PureComponent {constructor() {super()this.state = {titleSize: 30}}addTitleSize() {this.setState({ titleSize: this.state.titleSize + 2 })}render() {const { titleSize } = this.statereturn (<div><button onClick={e => this.addTitleSize()}>增加titleSize</button><h2 style={{color: "red", fontSize: `${titleSize}px`}}>我是标题</h2><p style={{color: "blue", fontSize: "20px"}}>我是内容, 哈哈哈</p></div>)}
}export default App

CSS Module

将CSS样式封装到组件中,为每个组件生成唯一的类名,确保样式作用域仅限于当前组件,从而避免样式冲突

步骤一:创建一个名为 App.module.css 的文件

.title {font-size: 32px;color: green;
}.content {font-size: 22px;color: orange;
}

步骤二:通过 import 导入 CSS Module 文件,并使用生成的类名

import React, { PureComponent } from 'react'
import Home from './home/Home'
import Profile from './profile/Profile'import appStyle from "./App.module.css"export class App extends PureComponent {render() {return (<div><h2 className={appStyle.title}>我是标题</h2><p className={appStyle.content}>我是内容, 哈哈哈哈</p><Home/><Profile/></div>)}
}export default App

工作原理:CSS Modules 在构建过程中会自动为每个类名生成一个唯一的哈希值

Less编写

1. 安装 Less 和相关依赖

npm install less less-loader --save-dev

2.配置 Webpack 支持 Less

对于 Create React App 项目

由于 Create React App 默认隐藏了 Webpack 配置,可以通过 craco(Create React App Configuration Override)来修改配置:

step1:安装 cracocraco-less

npm install @craco/craco craco-less --save-dev

step2:创建 craco.config.js 文件,并配置 Less:

const CracoLessPlugin = require('craco-less');module.exports = {plugins: [{plugin: CracoLessPlugin,options: {lessLoaderOptions: {lessOptions: {modifyVars: { '@primary-color': '#1e80ff' },javascriptEnabled: true,},},},},],
};

step3:修改 package.json 中的脚本命令,将 react-scripts 替换为 craco

"scripts": {"start": "craco start","build": "craco build","test": "craco test","eject": "react-scripts eject"
}

3.使用 Less 编写样式

step1:定义全局变量

@primaryColor: red;.section {border: 1px solid @primaryColor;.title {font-size: 30px;color: @primaryColor;}.content {font-size: 20px;color: @primaryColor;}
}

step2:在组件中使用 Less

import React, { PureComponent } from 'react'
import "./App.less"export class App extends PureComponent {render() {return (<div className='app'><div className='section'><h2 className='title'>我是标题</h2><p className='content'>我是内容, 哈哈哈</p></div></div>)}
}export default App

CSS in JS

React思想中认为逻辑本身和UI是无法分离的,所有才有了JSX语法;样式也是UI的一部分,CSS-in-JS就是将样式写入到JS或TS中的方式

1.工作原理:

  • 将样式定义在 JavaScript 中,并通过动态生成的类名或内联样式直接应用于组件
  • 这种方式使得样式的作用域完全限定在组件内部,避免了全局样式冲突

2.基本使用

step1:安装styled-components:使用模板字符串定义样式

npm i styled-components

step2:定义一个style.js文件

import styled from "styled-components"export const AppWrapper = styled.div`border: 1px solid orange;
`

step3:导入组件中

import React, { PureComponent } from 'react'
import { AppWrapper} from "./style"export class App extends PureComponent {render() {return (<AppWrapper><h2 className='title'>我是标题</h2><p className='content'>我是内容, 哈哈哈</p></AppWrapper>)}
}export default App

3.props接收数据

获取props需要通过${}传入一个插值函数,props会作为该函数的参数

4.attrs属性

用于传递一组额外的属性到组件中,通常与props一起使用

当传过来的有值时使用传过来的,没值时设置一个默认样式

export const SectionWrapper = styled.div.attrs(props => ({tColor: props.color || "blue"
}))`border: 1px solid red;.title {font-size: ${props => props.size}px;color: ${props => props.tColor};&:hover {background-color: purple;}}}
`

5.styled高级特性

支持样式继承

import styled from "styled-components";const HYButton = styled.button`border: 1px solid red;border-radius: 5px;
`export const HYButtonWrapper = styled(HYButton)`background-color: #0f0;color: #fff;
`

styled设置主题

可用来设置和管理主题样式

classnames库

我们在react中可借用一个第三方库classnames来动态添加某些类

step1:安装

npm install classnames

step2:使用

import React, { PureComponent } from 'react'
import classNames from 'classnames'export class App extends PureComponent {constructor() {super()this.state = {isbbb: true,isccc: true}}render() {const { isbbb, isccc } = this.stateconst classList = ["aaa"]if (isbbb) classList.push("bbb")if (isccc) classList.push("ccc")const classname = classList.join(" ")return (<div><h2 className={`aaa ${isbbb ? 'bbb': ''} ${isccc ? 'ccc': ''}`}>哈哈哈</h2><h2 className={classname}>呵呵呵</h2><h2 className={classNames("aaa", { bbb:isbbb, ccc:isccc })}>嘿嘿嘿</h2><h2 className={classNames(["aaa", { bbb: isbbb, ccc: isccc }])}>嘻嘻嘻</h2></div>)}
}export default App

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词