P26:React高级-多DOM动画制作和编写react-transition-group

Posted wgchen~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P26:React高级-多DOM动画制作和编写react-transition-group相关的知识,希望对你有一定的参考价值。

阐述

通过上一节的学习,只能控制一个DOM元素的动画,想控制多个动画 react-transition-group这个动画库也是可以做到的。

这节课就带你了解一下多DOM动画控制的方法。

使用 TransitionGroup

它就是负责多个DOM元素的动画的,我们还是拿服务这个案例作例子,现在可以添加任何的服务项目,但是都是直接出现的,没有任何动画,现在就给它添加上动画。

添加动画,先引入 transitionGrop

直接打开 /src/Beauty.js 的文件,然后在最顶部同时

import CSSTransition , TransitionGroup from 'react-transition-group'

引入之后,就可以使用这个组件了,方法是在外层增加 <TransitionGroup> 标签。

<ul ref=(ul)=>this.ul=ul>
    <TransitionGroup>
    
        this.state.list.map((item,index)=>
            return (
                <BeautyItem
                key=index+item  
                content=item
                index=index
                deleteItem=this.deleteItem.bind(this)
                />
            )
        )
    
    </TransitionGroup>
</ul>

这个需要放在循环的外边,这样才能形成一个组动画,但是只有这个<TransitonGroup>是不够的,你还是需要加入<CSSTransition>,来定义动画。

加入 <CSSTranstion> 标签

可以完全仿照上节课的经验,为 Beauty 组件,加上具体的动画设置,就可以实现多DOM元素的动画效果了。

代码如下:

<ul ref=(ul)=>this.ul=ul>
    <TransitionGroup>
    
        this.state.list.map((item,index)=>
            return (
                <CSSTransition
                    timeout=1000
                    classNames='boss-text'
                    unmountOnExit
                    appear=true
                    key=index+item  
                >
                    <MeinvItem 
                    content=item
                    index=index
                    deleteItem=this.deleteItem.bind(this)
                    />
                </CSSTransition>
            )
        )
    
    </TransitionGroup>
</ul>  
<Boss />
</Fragment>

demo

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import App from './Beauty'
ReactDOM.render(<App />,document.getElementById('root'))

Beauty.js

import React,Component,Fragment  from 'react'
import BeautyItem from './BeautyItem'
import axios from 'axios'
import CSSTransition , TransitionGroup from 'react-transition-group'
import Boss from './Boss'

class Beauty extends Component
//js的构造函数,由于其他任何函数执行
constructor(props)
    super(props) //调用父类的构造函数,固定写法
    this.state=
        inputValue:'' , // input中的值
        list:['基础按摩','精油推背']    //服务列表
    


componentDidMount()
    axios.get('http://tt.cc/')
        .then((res)=>
            // console.log(this.state.list)  res.data
            
            this.setState(
                list:[res.data.name,res.data.sex]
            )

        )
        .catch((error)=>
            console.log('axios 获取数据失败'+error)
        )


shouldComponentUpdate()
    console.log('shouldComponentUpdate---组件发生改变前执行')
    return true


componentWillUpdate()
    console.log('componentWillUpdate---组件更新前,shouldComponentUpdate函数之后执行')


render()
    return  (
        <Fragment>
            /* 正确注释的写法 */
            <div>
                <label htmlFor="willem">加入服务:</label>
                <input 
                id="willem" 
                className="input" 
                value=this.state.inputValue 
                onChange=this.inputChange.bind(this)
                //关键代码——----------start
                ref=(input)=>this.input=input
                //关键代码------------end
                />
                <button onClick=this.addList.bind(this)> 增加服务 </button>
            </div>
            <ul ref=(ul)=>this.ul=ul>
            <TransitionGroup>
            
                this.state.list.map((item,index)=>
                    return (
                        <CSSTransition
                            timeout=1000
                            classNames='boss-text'
                            unmountOnExit
                            appear=true
                            key=index+item  
                        >
                            <BeautyItem 
                            content=item
                            index=index
                            deleteItem=this.deleteItem.bind(this)
                            />
                        </CSSTransition>
                    )
                )
            
            </TransitionGroup>
        </ul>  
        <Boss />
        </Fragment>
    )


    // inputChange(e)
    //     // console.log(e.target.value);
    //     // this.state.inputValue=e.target.value;
    //     this.setState(
    //         inputValue:e.target.value
    //     )
    // 

    inputChange()
        console.log(this.input.value);
        this.setState(
            inputValue:this.input.value
        )
    
    
    //增加服务的按钮响应方法
    addList()
        this.setState(
            list:[...this.state.list,this.state.inputValue],
            inputValue:''
        )

    
   //删除单项服务
   deleteItem(index)
    let list = this.state.list
    list.splice(index,1)
    this.setState(
        list:list
    )



export default Beauty

BeautyItem.js

import React,  Component  from 'react'; //imrc
import PropTypes from 'prop-types'

class BeautyItem extends Component  //cc
   //--------------主要代码--------start
   constructor(props)
       super(props)
       this.handleClick=this.handleClick.bind(this)
   

   componentWillUnmount()
        console.log('child - componentWillUnmount')
    

    shouldComponentUpdate(nextProps,nextState)
        if(nextProps.content !== this.props.content)
            return true
        else
            return false
        

    

   //--------------主要代码--------end
   render()  
        console.log("child -- render")
        return ( 
            <li onClick=this.handleClick>
                this.props.avname为你服务-this.props.content</li>
        );
    
    handleClick()
        console.log(this.props.index)
        this.props.deleteItem(this.props.index)
    


BeautyItem.defaultProps = 
    avname:'苍井空'



//--------------主要代码--------start
BeautyItem.propTypes=
    content:PropTypes.string,
    deleteItem:PropTypes.func,
    index:PropTypes.number,
    avname:PropTypes.string.isRequired

//--------------主要代码--------end

export default BeautyItem;

Boss.js

import React,  Component  from 'react';
import  CSSTransition  from 'react-transition-group'
import './exp.css'

class Boss extends Component 
    constructor(props) 
        super(props);
        this.state =  
            isShow:true
        
        this.toToggole = this.toToggole.bind(this);
    

    render()  
        return ( 
            <div>
                <CSSTransition 
                    in=this.state.isShow   //用于判断是否出现的状态
                    timeout=2000           //动画持续时间
                    classNames="boss-text"   //className值,防止重复
                    unmountOnExit
                >
                    <div>BOSS级人物-孙悟空</div>
                </CSSTransition>
                <div><button onClick=this.toToggole>召唤Boss</button></div>
            </div>
            );
    

    toToggole()
        this.setState(
            isShow:this.state.isShow ? false : true
        )
    

 
export default Boss;

exp.css

.input border:3px solid #ae7000

.boss-text-enter
    opacity: 0;

.boss-text-enter-active
    opacity: 1;
    transition: opacity 2000ms;


.boss-text-enter-done
    opacity: 1;

.boss-text-exit
    opacity: 1;

.boss-text-exit-active
    opacity: 0;
    transition: opacity 2000ms;


.boss-text-exit-done
    opacity: 0;

接口 php

<?php
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: token,Origin, X-Requested-With, Content-Type, Accept");
header('Access-Control-Allow-Methods: POST,GET');

// yield方式
// 耗时0.2580891秒
// 内存: 339K
$res = [
    'name'=>'willem',
    'age'=>31,
    'sex'=>'man',
    'user_id'=>$_GET['ID']
];

echo json_encode($res, JSON_UNESCAPED_UNICODE);

以上是关于P26:React高级-多DOM动画制作和编写react-transition-group的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript学习之DOM高级操作(动画)

JavaScript一线大厂面试秘籍:面向对象+domom+事件+特性动画+面试题+基础

最小化浏览器重排/重新渲染

Javascript高级程序设计之DOM

JS高级-异步

20200109 《jQuery基础教程》归档