react中使用过渡动画

官方文档

https://reactcommunity.org/react-transition-group/

安装

cnpm i --save-dev react-transition-group
"react-transition-group": "^4.4.2",

插件中的组件

  • Transition

  • CSSTransition

  • SwitchTransition

  • TransitionGroup

CSSTransition css过渡组件

分为入场动画和过渡动画

  1. *-enter-active表示想要动画到那些样式

  2. *-exit-active 表示离开之后的动画

属性

classNames属性是在组件进入、退出时应用于组件的动画类名称。每个阶段都会加上后缀,

例如

.fade-enter  入场动画第一帧
.fade-enter-active 入场动画第二帧
.fade-enter-done 入场动画执行完成
.fade-exit 出场动画第一帧
.fade-exit-active 出场动画第二帧
.fade-exit-done 出场动画结束
.fade-appear
.fade-appear-active 功能和入场动画一致  需要添加属性appear={true}  首次渲染时执行动画
​​

import './App.css'
import { useState } from 'react'
//引入过渡动画
import { CSSTransition } from 'react-transition-group'
console.log(CSSTransition);
function App() {
  let [show, setShow] = useState(true);
  let handle = function () {
    setShow(!show);
  }
  return (
    
          App组件     ​      
) } ​ export default App ​ ​ .fade-enter,.fade-appear{   opacity: 0; } .fade-enter-active,.fade-appear-active{   opacity: 1;   transition: opacity .5s; } .fade-exit{   opacity: 1; } .fade-exit-active{   opacity: 0;   transition: opacity .5s; } .fade-exit-done{   opacity: 0; } ​

如果实现多个标签动画使用动画组

TransitionGroup组件

路由组件实现动画

 
      
        
          
            
          
          
            
          
          
            
          
        
      
    
.fade-enter {
  opacity: 0;
  transform: translateX(100%);
}
​
.fade-enter-active {
  opacity: 1;
  transform: translateX(0);
  transition: all 500ms;
}
​
.fade-exit {
  opacity: 1;
  transform: translateX(0);
}
​
.fade-exit-active {
  opacity: 0;
  transform: translateX(-100%);
  transition: all 500ms;
}

如何实现路由组件根据路由的进入和离开 控制动画

childFactory
您可能需要在孩子退出时对其应用响应式更新。这通常是通过使用来完成的,cloneElement但是在现有子元素的情况下,该元素已被删除并且消费者无法访问。
​
如果您确实需要在孩子离开时对其进行更新,您可以提供一个childFactory 来包装每个孩子,即使是那些正在离开的孩子。
​
类型:Function(child: ReactElement) -> ReactElement
默认:child => child

多个动画切换

// src/App6/RouteConfig.js
export const RouterConfig = [
  {
    path: '/',
    component: HomePage
  },
  {
    path: '/about',
    component: AboutPage,
    sceneConfig: {
      enter: 'from-bottom',
      exit: 'to-bottom'
    }
  },
  {
    path: '/list',
    component: ListPage,
    sceneConfig: {
      enter: 'from-right',
      exit: 'to-right'
    }
  },
  {
    path: '/detail',
    component: DetailPage,
    sceneConfig: {
      enter: 'from-right',
      exit: 'to-right'
    }
  }
];

index.js

// src/App6/index.js
const DEFAULT_SCENE_CONFIG = {
  enter: 'from-right',
  exit: 'to-exit'
};
​
const getSceneConfig = location => {
  const matchedRoute = RouterConfig.find(config => new RegExp(`^${config.path}$`).test(location.pathname));
  return (matchedRoute && matchedRoute.sceneConfig) || DEFAULT_SCENE_CONFIG;
};
​
let oldLocation = null;
const Routes = withRouter(({location, history}) => {
​
  // 转场动画应该都是采用当前页面的sceneConfig,所以:
  // push操作时,用新location匹配的路由sceneConfig
  // pop操作时,用旧location匹配的路由sceneConfig
  let classNames = '';
  if(history.action === 'PUSH') {
    classNames = 'forward-' + getSceneConfig(location).enter;
  } else if(history.action === 'POP' && oldLocation) {
    classNames = 'back-' + getSceneConfig(oldLocation).exit;
  }
​
  // 更新旧location
  oldLocation = location;
​
  return (
     React.cloneElement(child, {classNames})}
    >
      
        
          {RouterConfig.map((config, index) => (
            
          ))}
        
      
    
  );
});
vite工具配置@

export default defineConfig({
  plugins: [react()],
  resolve:{
    alias:{
      "@":resolve('src')
    }
  }
})
​

react原生项目中配置@

安装@craco/craco

在src同级目录创建文件

// src/App6/index.js
const DEFAULT_SCENE_CONFIG = {
  enter: 'from-right',
  exit: 'to-exit'
};
​
const getSceneConfig = location => {
  const matchedRoute = RouterConfig.find(config => new RegExp(`^${config.path}$`).test(location.pathname));
  return (matchedRoute && matchedRoute.sceneConfig) || DEFAULT_SCENE_CONFIG;
};
​
let oldLocation = null;
const Routes = withRouter(({location, history}) => {
​
  // 转场动画应该都是采用当前页面的sceneConfig,所以:
  // push操作时,用新location匹配的路由sceneConfig
  // pop操作时,用旧location匹配的路由sceneConfig
  let classNames = '';
  if(history.action === 'PUSH') {
    classNames = 'forward-' + getSceneConfig(location).enter;
  } else if(history.action === 'POP' && oldLocation) {
    classNames = 'back-' + getSceneConfig(oldLocation).exit;
  }
​
  // 更新旧location
  oldLocation = location;
​
  return (
     React.cloneElement(child, {classNames})}
    >
      
        
          {RouterConfig.map((config, index) => (
            
          ))}
        
      
    
  );
});
vite工具配置@

export default defineConfig({
  plugins: [react()],
  resolve:{
    alias:{
      "@":resolve('src')
    }
  }
})
​

你可能感兴趣的:(前端,javascript,css,react.js)