Skip to content

Commit

Permalink
fail playlist animation
Browse files Browse the repository at this point in the history
  • Loading branch information
lz-lee committed Feb 26, 2018
1 parent 331d281 commit 288dbd6
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 81 deletions.
58 changes: 37 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,15 @@

- npm start

### 知识点
### 坑🐸

#### 1、refs
#### 1、生命周期执行顺序(网络截图)

- 获取 `refs`:以下方式均可以通过 `this.refs.input` 获取

```
<input ref={input => this.input = input}>
<input ref="input">
```
#### 2、生命周期执行顺序
> will mount (执行一次)
> will mount (执行一次)
> render
> did mount (执行一次)
> did mount (执行一次)
> will receive props
Expand All @@ -38,14 +27,14 @@
![生命周期](./assets/lifecycle.png)


#### 3、`componentWillReceiveProps(nextProps)` 与 `shouldComponentUpdate(newProps, newState)`
#### 2`componentWillReceiveProps(nextProps)``shouldComponentUpdate(newProps, newState)`

- 组件中的 `this.props` 与 这两个生命周期中的 `nextProps 、newProps` 是同一个引用

- 与vue不同,vue是diff数据,react是diff的dom,react需要手动set数据,因此在这两个钩子函数里做watch数据相关操作再决定是否重新render


#### 4、动画 [react-transition-group](https://reactcommunity.org/react-transition-group/#CSSTransition-prop-onEntered)
#### 3、动画 [react-transition-group](https://reactcommunity.org/react-transition-group/#CSSTransition-prop-onEntered)

- `CSSTranstion` 模块: 嵌套动画,需要将

Expand Down Expand Up @@ -82,13 +71,40 @@
```
- `TransitionGroup` 模块用来做删除列表的动画
- 不足之处:无法对子路由切走时(即没有dom元素时)应用 `exit、exit-active` 动画
- `TransitionGroup` 模块用来做删除列表的动画, 类似 `vue` 的 `<transition-group> `
#### 4、mixin
- 如何调用被装饰后的子组件的方法?大量需要调用子组件方法控制显示隐藏的地方
- `search` 组件调用被 `connect` 过后的 `suggest` 组件的 `refresh` 方法
- `player` 组件调用 `playList` 的 `show` 方法
- ...
- 获取被 `connect` 后(高阶化)组件的 `ref`
- 查看[react-redux](https://github.com/reactjs/react-redux/blob/master/docs/api.md)的API文档,`connect`是基于 `connectAdvanced`的,connect 接受的第四个参数 `options` ![](./assets/connect.jpeg)![](./assets/connectadvance.jpeg)可以进一步自定义 `connector` 的行为,除了可以传入 `connectAdvanced` 的选项外……,往下翻到 `connectAdvanced` 发现被隐藏的api及其配置 ![](./assets/connectoptions.jpeg),就是这个 `withRef`, 如果配置为 `true`,则被 `connect` 包装后的组件实例会获得一个 `getWrappedInstance()` 方法,此方法返回被包装之前的 `ReactComponent` ![](./assets/instancemethods.jpeg)。注意 `options` 参数一定要是在第四个参数才会生效。
- 大牛源码解析[庖丁解牛React-Redux(一): connectAdvanced](https://github.com/MrErHu/blog/issues/17)
- 大牛源码解析[庖丁解牛React-Redux(二): connect](https://github.com/MrErHu/blog/issues/19)
- 此外获取引用的常见方法:
- 获取 `refs`:以下方式均可以通过 `this.refs.input` 获取
```
<input ref={input => this.input = input}>
#### 5、mixin
<input ref="input">
- 如何调用被装饰后的子组件的方法?
```
- `search` 组件无法调用被 `connect` 过后的 `suggest` 组件的 `refresh` 方法
- [官网](https://reactjs.org/docs/refs-and-the-dom.html)并不推荐过度使用 `refs` 操作 `DOM`,指定显示隐藏方法,不如传递属性
- 自定义高阶组件获取子组件 `ref` 和 `connect` 类似
- [HOC](https://segmentfault.com/a/1190000008112017#articleHeader12)
Binary file added assets/connect.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/connectadvance.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/connectoptions.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/instancemethods.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 5 additions & 4 deletions src/common/styl/index.styl
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,11 @@
transition: all 0.3s
&.list-fade-exit
opacity 1
transform translate3d(0, 0 0)
.list-wrapper
transform translate3d(0, 0 0)
&.list-fade-exit-active
opacity: 0
transition all 0.3s
.list-wrapper
transform: translate3d(0, 100%, 0)
transition all 0.3s
.list-wrapper
transform: translate3d(0, 100%, 0)
transition all 0.3s
145 changes: 90 additions & 55 deletions src/components/playList/playList.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
import {connect} from 'react-redux'

import {CSSTransition, TransitionGroup} from 'react-transition-group'
import {Transition, TransitionGroup, CSSTransition} from 'react-transition-group'

import Scroll from 'base/scroll/scroll'
import Confirm from 'base/confirm/confirm'
Expand All @@ -10,12 +10,34 @@ import {playMode} from 'common/js/config'

import './playList.styl'

const defaultStyle = {
transition: 'all 0.3s',
opacity: 0,
}

const transitionStyle = {
entering: { opacity: 0 },
entered: { opacity: 1 }
}

const wrapperStyle = {
transition: 'all 0.3s',
transform: 'translate3d(0, 100%, 0)'
}

const wrapperTransitionStyle = {
entering: { transform: 'translate3d(0, 100%, 0)' },
entered: { transform: 'translate3d(0, 0, 0)' }
}

class PlayList extends React.Component{
constructor(props) {
super(props)
this.state = {
showFlag: false
}
this.show = this.show.bind(this)
this.getWrappedInstance = this.getWrappedInstance.bind(this)
}

show() {
Expand All @@ -24,72 +46,85 @@ class PlayList extends React.Component{
})
}

getWrappedInstance() {
if (this.props.withRef) {
return this.wrappedInstance
}
}

render() {
const {player: {mode}} = this.props
const modeText = mode === playMode.sequence ? '顺序播放' : mode === playMode.random ? '随机播放' : '单曲循环'
const modeIcon = mode === playMode.sequence ? 'icon-sequence' : mode === playMode.loop ? 'icon-loop' : 'icon-random'
return (
<CSSTransition
<Transition
in={this.state.showFlag}
timeout={200}
classNames="list-fade">
<div className="playlist">
<div className="list-wrapper">
<div className="list-header">
<h1 className="title">
<i className={"icon " + modeIcon}></i>
<span className="text">{modeText}</span>
<span className="clear"><i className="icon-clear"></i></span>
</h1>
</div>
<Scroll
ref="listContent"
className="list-content"
probeType={3}
>
<TransitionGroup>
{
this.props.player.sequenceList.map((v, i) =>
<CSSTransition
key={v.id}
timeout={200}
classNames="list"
>
<li className="item">
<i className="current"></i>
<span className="text"></span>
<span className="like">
<i></i>
</span>
<span className="delete">
<i className="icon-delete"></i>
</span>
</li>
</CSSTransition>
)
}
</TransitionGroup>
</Scroll>
<div className="list-operate">
<div className="add">
<i className="icon-add"></i>
<span className="text">添加歌曲到队列</span>
{
(state) => (
<div className="playlist" style={{
...defaultStyle,
...transitionStyle[state]
}}>
<div className="list-wrapper">
<div className="list-header">
<h1 className="title">
<i className={"icon " + modeIcon}></i>
<span className="text">{modeText}</span>
<span className="clear"><i className="icon-clear"></i></span>
</h1>
</div>
<Scroll
ref="listContent"
className="list-content"
probeType={3}
>
<TransitionGroup>
{
this.props.player.sequenceList.map((v, i) =>
<CSSTransition
key={v.id}
timeout={200}
classNames="list"
>
<li className="item">
<i className="current"></i>
<span className="text"></span>
<span className="like">
<i></i>
</span>
<span className="delete">
<i className="icon-delete"></i>
</span>
</li>
</CSSTransition>
)
}
</TransitionGroup>
</Scroll>
<div className="list-operate">
<div className="add">
<i className="icon-add"></i>
<span className="text">添加歌曲到队列</span>
</div>
</div>
<div className="list-close">
<span>关闭</span>
</div>
</div>
<Confirm
ref="confirm"
text="是否清空所有搜索历史"
confirmBtnText="清空"
></Confirm>
</div>
<div className="list-close">
<span>关闭</span>
</div>
</div>
<Confirm
ref="confirm"
text="是否清空所有搜索历史"
confirmBtnText="清空"
></Confirm>
</div>
</CSSTransition>
)
}
</Transition>
)
}
}

PlayList = connect(state => state)(PlayList)
PlayList = connect(state => state, null, null, {withRef: true})(PlayList)
export default PlayList
5 changes: 4 additions & 1 deletion src/components/player/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class Player extends React.Component{
this.touchStart = this.touchStart.bind(this)
this.touchMove = this.touchMove.bind(this)
this.touchEnd = this.touchEnd.bind(this)
this.showPlaylist = this.showPlaylist.bind(this)
}

static propTypes = {
Expand Down Expand Up @@ -422,7 +423,9 @@ class Player extends React.Component{

showPlaylist(e) {
e.stopPropagation()
this.refs.playList.show()
console.log(this.refs.playList)
let playListInstance = this.refs.playList.getWrappedInstance()
playListInstance.show()
}

changeMode() {
Expand Down

0 comments on commit 288dbd6

Please sign in to comment.