业务描述
在如上图所示的页面上我需要分别点击底下的三个图标将中间内容部分分别替换成对应的组件,也就是在一个大组件中分别切换三个小组件
效果展示
因为是移动端,请按F12切换成移动端
思路
通过控制css属性display:none来控制三个页面是谁来显示,中间主要是组件之间的通讯值得一说
实现
1 首先简单写好三个子组件
/*通讯录*/class PageChatContent extends React.Component{ constructor(props){ super(props); } render(){ return ( <div className={this.props.chatShow+" "+universal.content} >chat</div> ) } }/*微博社交*/class PageSocialContent extends React.Component{ constructor(props){ super(props); } render(){ return ( <div className={this.props.socialShow+" "+universal.content}>social</div> ) } }/*朋友圈*/class CircleSocialContent extends React.Component{ constructor(props){ super(props); } render(){ return ( <div className={this.props.circleShow+" "+universal.content}>circle</div> ) } }
2将子组件填到父组件中
return( <div className={universal.content+" "+universal.columnCenter}> <div className={jsPage.heard}> <img src={this.state.imgAddress} className={jsPage.imgStyle}></img> </div> <div className={jsPage.body+" "+universal.rowStartWrap}> <PageChatContent chatShow={this.state.chatShow}></PageChatContent> <PageSocialContent socialShow={this.state.socialShow}></PageSocialContent> <CircleSocialContent circleShow={this.state.circleShow}></CircleSocialContent> </div> <div className={jsPage.bottom}> <JsPageBottomNavigation history={this.props.history} changePage={msg=>this.changePage(msg)} ></JsPageBottomNavigation> </div> </div> )
3 通过设置state来设置初始显示
this.state={ chatShow:"", socialShow:jsPage.showFlag, circleShow:jsPage.showFlag, msg:"" }
jsPage.showFlag是我设置的css
import jsPage from '../css/jsPage.css'
.showFlag{ display: none;}
<PageChatContent chatShow={this.state.chatShow}></PageChatContent> <PageSocialContent socialShow={this.state.socialShow}></PageSocialContent> <CircleSocialContent circleShow={this.state.circleShow}></CircleSocialContent>
4 底部导航栏的实现
通过map遍历数据生成
class JsPageBottomNavigation extends React.Component{ constructor(props){ super(props); this.changeFrom = this.changeFrom.bind(this); } render(){ //需要遍历生产的数据 const posts = [ {id: 1, name:'chat',imgUrl:sysImg1}, {id: 2, name:'social',imgUrl:sysImg2}, {id: 3, name:'circle',imgUrl:sysImg3}, ]; const fromList=posts.map( (number)=> <div className={universal.columnCenter+" "+universal.content} key={number.id}> <img src={number.imgUrl} className={jsPage.imgStyle1} onClick={ () =>this.props.changePage(number.name)} ></img> </div> ); return ( <div className={index.bottomNavigation+" "+universal.rowCenter}> <div className={index.fromList+" "+universal.rowCenter} > {fromList} </div> </div> ) } }
5,通讯!最关键的部分
因为我要通过我的底部子组件的点击来改变我中间子组件的显示内容,属于
兄弟组件的通讯,实现方式就是将数据通过他们的共同父组件来传递,
也就是导航组件将数据传到父组件,父组件再将数据传到显示组件
首先我在父组件定义一个方法,并将方法传到导航组件中
changePage(msg){ this.setState({ msg });}
注意:一定要使用箭头函数,因为箭头函数的this作用域始终作用于生产箭头函数的地方,这样我们就可以听过让子函数来修改组件的state里面的值,从而达到传值的目的,就像上面的方法中的msg要首先在state中定义
<JsPageBottomNavigation history={this.props.history} changePage={msg=>this.changePage(msg)} ></JsPageBottomNavigation>
然后,在子组件的map遍历中每个图标点击调用的方法参数都会不同,通过点击子组件不同的图标,将会传不同的值到父组件
const posts = [ {id: 1, name:'chat',imgUrl:sysImg1}, {id: 2, name:'social',imgUrl:sysImg2}, {id: 3, name:'circle',imgUrl:sysImg3}, ]; const fromList=posts.map( (number)=> <div className={universal.columnCenter+" "+universal.content} key={number.id}> <img src={number.imgUrl} className={jsPage.imgStyle1} onClick={ () =>this.props.changePage(number.name)} ></img> </div> );
在父组件中通过接受到不同的值,然后做出对应的处理,最后将处理好的值传到显示子组件,这样就完成了组件间的通讯
changePage(msg){ this.setState({ msg }); console.log(msg) if(msg=="chat"){ this.setState( { chatShow:"", socialShow:jsPage.showFlag, circleShow:jsPage.showFlag, }) } if(msg=="social"){ this.setState( { chatShow:jsPage.showFlag, socialShow:"", circleShow:jsPage.showFlag, }) } if(msg=="circle"){ this.setState( { chatShow:jsPage.showFlag, socialShow:jsPage.showFlag, circleShow:"", }) } }