React-Router动画实际上和React动画没什么区别,都是使用 'react-addons-css-transition-group' 这个组件;但是,和普通的 React-Router 的 App 的写法稍有t不同;
通常我们这样定义一个使用了 React-Router 的组件
export default React.createClass({ render() { return <div> {this.props.children} </div> } })
但是当需要使用 ReactCSSTransitonGroup 的时候,需要写成如下:
const App = ({children, location}) => ( <div> <CSSTransitionGroup component="div" transitionName="page" transitionAppear={true} transitionAppearTimeout={1500} transitionEnterTimeout={1500} transitionLeaveTimeout={1500}> {React.cloneElement(children, { key: location.pathname })} </CSSTransitionGroup> </div> )
上面是一个最基础的使用 ReactCSSTransitonGroup 的 App。
下面是几个示例:
Demo1: 参考自官方示例
var React = require('react'); var ReactDOM = require('react-dom'); var CSSTransitionGroup = require('react-addons-css-transition-group'); var ReactRouter = require('react-router'); var Router = ReactRouter.Router; var Route = ReactRouter.Route; var hashHistory = ReactRouter.hashHistory; var IndexRoute = ReactRouter.IndexRoute; var Link = ReactRouter.Link; const App = ({children, location}) => ( <div> <ul> <li><Link to="/page1">Page 1</Link></li> <li><Link to="/page2">Page 2</Link></li> </ul> <CSSTransitionGroup component="div" transitionName="page" transitionAppear={true} transitionAppearTimeout={1500} transitionEnterTimeout={1500} transitionLeaveTimeout={1500}> {React.cloneElement(children, { key: location.pathname })} </CSSTransitionGroup> </div> ) const Index = () => ( <div className="Image"> <h1>Index</h1> <p>Animations with React Router are not different than any other animation.</p> </div> ) const Page1 = () => ( <div className="Image"> <h1>Page 1</h1> <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip exea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> </div> ) const Page2 = () => ( <div className="Image"> <h1>Page 2</h1> <p>Consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> </div> ) ReactDOM.render(( <Router history={hashHistory}> <Route path="/" component={App}> <IndexRoute component={Index}/> <Route path="page1" component={Page1}/> <Route path="page2" component={Page2}/> </Route> </Router> ), document.getElementById('container'));
Demo2
var React = require('react'); var ReactDOM = require('react-dom'); var CSSTransitionGroup = require('react-addons-css-transition-group'); var ReactRouter = require('react-router'); var Router = ReactRouter.Router; var Route = ReactRouter.Route; var hashHistory = ReactRouter.hashHistory; var IndexRoute = ReactRouter.IndexRoute; var Link = ReactRouter.Link; var Index = ()=>(<div>Index</div>) var App3 = ()=> (<div className="page1">ABCDEFGHIJKLMN</div>) var App4 = ()=> (<div className="page2">ABCDEFGHIJKLMNFKFKFKFK</div>) const App = ({children, location}) => ( <div> <CSSTransitionGroup component="div" transitionName="page" transitionAppear={true} transitionAppearTimeout={1500} transitionEnterTimeout={1500} transitionLeaveTimeout={1500}> {React.cloneElement(children, { key: location.pathname })} </CSSTransitionGroup> </div> ); ReactDOM.render( <Router history={hashHistory}> <Route path="/" component={App}> <IndexRoute component={Index}/> <Route path="page1" component={App3}/> <Route path="page2" component={App4}/> </Route> </Router>, document.getElementById('container'));
Demo3:
还可以不使用如上的方式,转而将每个App都使用 ReactCSSTransitionGroup 封装
var React = require('react'); var ReactDOM = require('react-dom'); var CSSTransitionGroup = require('react-addons-css-transition-group'); var ReactRouter = require('react-router'); var Router = ReactRouter.Router; var Route = ReactRouter.Route; var hashHistory = ReactRouter.hashHistory; var IndexRoute = ReactRouter.IndexRoute; var App1 = React.createClass({ handleClick: function () { this.props.router.push('/page2'); }, render: function () { return ( <CSSTransitionGroup transitionName="page" transitionAppear={true} transitionAppearTimeout={1500} transitionEnterTimeout={1500} transitionLeaveTimeout={1500}> <div onClick={this.handleClick} className="page1">ABC</div> </CSSTransitionGroup> ) } }); var App2 = React.createClass({ handleClick: function () { this.props.router.goBack(); }, render: function () { return ( <CSSTransitionGroup transitionName="page" transitionAppear={true} transitionAppearTimeout={1500} transitionEnterTimeout={1500} transitionLeaveTimeout={1500}> <div onClick={this.handleClick} className="page2">ABCDEFGHIJKLMN</div> </CSSTransitionGroup> ) } }); var App = ()=>(<div>Welcome App</div>) ReactDOM.render( <Router history={hashHistory}> <Route path="/page1" component={App1}></Route> <Route path="/page2" component={App2}></Route> </Router>, document.getElementById('container'));
page及相关样式
.page-appear { opacity: 0.01; margin-left: 100%; -webkit-transition: all 1.5s; transition: all 1.5s; } .page-appear.page-appear-active { margin-left: 0px; opacity: 1; } .page-enter { opacity: 0.01; margin-left: 100%; -webkit-transition: all 1.5s; transition: all 1.5s; } .page-enter.page-enter-active { margin-left: 0px; opacity: 1; } .page-leave { opacity: 1; margin-left: 0px; -webkit-transition: all 1.5s; transition: all 1.5s; } .page-leave.page-leave-active { margin-left: -100%; opacity: 0.01; } .page1 { position: absolute; background-color: red; height: 100%; 100%; min-height: 400px; } .page2 { position: absolute; background-color: deepskyblue; height: 100%; 100%; min-height: 400px; } .Image { position: absolute; height: 400px; 400px; } .link-active { color: #bbbbbb; text-decoration: none; }
样式定义参考:[Link]