实现路由动效过渡,并解决过程中奇奇怪怪的问题

news/2024/7/7 15:12:06

前言

写这个只是更好的梳理下我实现过程中遇到的奇奇怪怪的问题,

因为着实浪费了我不少时间…肯定有不少也碰到过其中的问题

希望对小伙伴有所帮助。

效果图

  • 我命名为spread的效果,其实就是结合放大和旋转以及透明度的特性



  • 渐隐渐现fade



基础依赖

  • styled-components@3.4.2 : 写样式的
  • react-transition-group@2.4.0 : 路由过渡的,react官方的
  • react-router-dom@4.3.1 : react自家路由
  • react@16.4.2

问题有三,亦能解决

组件堆叠问题

就是再次进入路由切换的时候,之前的元素还没有消失,而新的组件渲染了,同时出现

  • 堆叠问题,只能用脱离文档流来解决,所以用position:absolute来负责渲染区域即可
  • 注意父层需要position:relative, 不然会一直往上找相对位置,实在找不到会相对窗口

点击侧边栏,组件一直重复渲染的问题

  • 一开始想的是去子组件区域,用shouldComponentUpdate来判断URL然后阻止渲染,发现不可行
  • 因为过渡外部用的location.key是随机性的,所以组件每次都会重新渲染
  • 最终的解决方案,是改掉了侧边栏的Link组件,直接用事件绑定(history.push来跳转),完美


随机切换效果

  • 这个结合CSSTransition的特性,因为location.key是随机性的,不同值都会走一遍;
  • 那样式的绑定给个随机数就好了.随机的范围根据你添加的个数进行调整,
  • Math.random()默认返回0~1随机浮点数,这里只有两个就不用成个数了


代码实现

重复渲染的解决逻辑代码

    // 路由跳转
    gotoUrl = itemurl => {
        // 拿到路由相关的信息
        const { history, location } = this.props;
        // 判断我们传入的静态路由表的路径是否和路由信息匹配
        // 不匹配则允许跳转,反之打断函数
        if (location.pathname === itemurl) {
            return;
        } else {
            history.push(itemurl);
        }
    };

复制代码


组件堆叠及过渡实现(包括随机)

import React, { Component } from 'react';
import { TransitionGroup, CSSTransition } from 'react-transition-group';
import { Route, Redirect, withRouter, Switch } from 'react-router-dom';
import styled from 'styled-components';
import { observer, inject } from 'mobx-react';
import asyncComponent from 'components/asyncComponent/asyncComponent';

const RouterAnimationClass = styled.div`
    .fade-appear,
    .fade-enter {
        opacity: 0;
    }

    .fade-appear-active,
    .fade-enter-active {
        transition: opacity 0.3s linear;
        opacity: 1;
    }

    .fade-exit {
        transition: opacity 0.2s linear;
        opacity: 1;
    }

    .fade-exit-active {
        opacity: 0;
    }

    .spread-appear,
    .spread-enter {
        opacity: 0.5;
        transform: scale(0) rotate(30deg);
    }

    .spread-appear-active,
    .spread-enter-active {
        opacity: 1;
        transform: scale(1) rotate(0);
        transition: transform 0.3s ease-in-out;
    }

    .spread-exit {
        transition: transform 0.2s ease-in-out;
        transform: scale(1.2) rotate(-30deg);
    }

    .spread-exit-active {
        transform: scale(0) rotate(0);
    }

    .page-content {
        position: absolute;
        left: 0;
        top: 0;
        bottom: 0;
        right: 0;
        width: 100%;
    }
`;

const Monitor = asyncComponent(() => import('pages/DashBoard/Monitor'));
const Analyze = asyncComponent(() => import('pages/DashBoard/Analyze'));

import ErrorPage from 'pages/Error/Error'; // 报错页面
@inject('auth')
@withRouter
@observer
class Container extends Component {
    constructor(props) {
        super(props);
    }
    render() {
        const { location } = this.props;
        return (
            <RouterAnimationClass>
                <TransitionGroup>
                    <CSSTransition
                        key={location.key}
                        classNames={
                            ['fade', 'spread'][parseInt(Math.random(), 10)]
                        }
                        timeout={1000}>
                        <div className="page-content">
                            <Switch location={location}>
                                <Route
                                    path="/dashboard/monitor"
                                    exact
                                    component={Monitor}
                                />
                                <Route
                                    path="/dashboard/analyze"
                                    exact
                                    component={Analyze}
                                />
                                <Redirect
                                    exact
                                    from="/"
                                    to="/dashboard/monitor"
                                />
                                <Route component={ErrorPage} />
                            </Switch>
                        </div>
                    </CSSTransition>
                </TransitionGroup>
            </RouterAnimationClass>
        );
    }
}

export default Container;
复制代码


转载于:https://juejin.im/post/5ced2be0f265da1bc4143462


http://www.niftyadmin.cn/n/3059044.html

相关文章

Linux内核中添加驱动模块到menuconfig中

Linux中驱动模块的加载有两种方法&#xff1a; 1.编译成.ko文件在内核启动后&#xff0c;动态的加载到内核中。 2.在内核编译的时候同时编译驱动模块。 现主要介绍第二种方案&#xff1a; 希望将内核驱动加载到内核模块中&#xff0c;需要在menuconfig菜单中选择配置。 首…

Android消息机制 Handler源码阅读

什么是Handler Handler允许您发送和处理与线程MessageQueue关联的Message和Runnable对象&#xff0c;每个Handler的实例都与一个线程的MessageQueue相关联&#xff0c;当你创建一个新的Handler时&#xff0c;它将被绑定到创建它的线程的MessageQueue&#xff0c;从绑定时起它可…

eas之辅助编辑功能

copy、cut、paste// copytable.getEditHelper().copy();// cuttable.getEditHelper().cut();// pastetable.getEditHelper().paste();table.getEditHelper().isPastable (); //是否有可paste的有效数据delete// 删除选择区域table.getEditHelper().delete();// 删除指定的区域…

使用 cd - 时出现bash: cd: OLDPWD not set的错误信息

在Linux中使用cd -&#xff0c;出现入下错误&#xff1a; bash: cd: OLDPWD not set 是因为开始打开终端&#xff0c;第一次操作cd命令的原因。 cd - 的作用是进入上一次cd的目录&#xff0c;也就是说cd命令后面的参数“-”&#xff0c;是代替上一次cd后面的参数。 同样cd …

Linux shell中if [ $? -eq 0 ] 语句作用:判断命令是否执行成功

shell脚本中$?是指上一次命令执行的成功或者失败的状态。如果成功就是0&#xff0c;失败为1.。语句if [ $? -eq 0 ] 是判断if语句的上一个命令执行如果成功就执行if中的语句&#xff0c;否则就执行else中的内容。 note&#xff1a;使用时要注意&#xff0c;if后面的中括号[ …

Linux shell中BASH_EOURCE和BASH_SOURCE[0]的作用:取得当前执行的shell脚本的相对路径

BASH_EOURCE和BASH_SOURCE[0]的作用都是一样的&#xff0c;就是取得当前执行的shell脚本的相对路径 如果希望获得&#xff0c;当前执行脚本的绝对路径&#xff0c;可以采用以下方式&#xff1a; DIR_T"$( cd "$(dirname "${BASH_SOURCE[0]}")" &…

linux shell中的$()和${}的区别

linux shell中的$()和${}的区别: $()中()里面的是执行的命令&#xff0c;与反引号同样效果。 如&#xff1a;$(cd $(dirname $0)) ${}中{}里面是具体的变量,作用是提取变量里面的内容。 如&#xff1a; VAR11 ${VAR1}

git push 小结

$ git push ssh://gitdev.lemote.com/rt4ls.git master // 把本地仓库提交到远程仓库的master分支中 $ git remote add origin ssh://gitdev.lemote.com/rt4ls.git $ git push origin master 这两个操作是等价的&#xff0c;第二个操作的第一行的意思是添加一个标记&#xff…