到目前爲止,首頁、文章詳情頁、動態頁、話題頁及小冊頁面內容完成了,看一下效果圖哈,數據不全,見諒哈! vue
該頁面從佈局來講分左右兩部分,左邊有分爲輸入框和已發表內容部分。react
<div style={{background:'#fff',padding:'15px',position:'relative'}}>
<TextArea placeholder="告訴你個小祕密,發沸點時添加話題會被更多小夥伴看見呦~" style={{paddingBottom:'30px'}} autosize={{ minRows: 3}} onChange={this.handelInputChange.bind(this)}/>
{this.state.selectedTopic!==''?<span style={{position:'absolute',bottom:'60px',left:'28px',padding:'0 12px',border:'1px solid #007fff',userSelect:'none',height:'22px',borderRadius:'14px',color:'#007fff'}}>{this.state.selectedTopic}</span>:''}
<div style={{marginTop:'5px',display:'flex',justifyContent:'space-between'}}>
<ul style={sy1}>
<li style={sy2} onClick={this.handleBtn.bind(this,'exp')}>
<img alt='' src='//b-gold-cdn.xitu.io/v3/static/img/emoji.5594dbb.svg' />表情
</li>
<li style={sy2} onClick={this.handleBtn.bind(this,'pic')}>
<img alt='' src='//b-gold-cdn.xitu.io/v3/static/img/active_file.d265f4e.svg' />圖片
</li>
<li style={sy2} onClick={this.handleBtn.bind(this,'link')}>
<img alt='' src='//b-gold-cdn.xitu.io/v3/static/img/active_link.b1a6832.svg' />連接
</li>
<Popover placement="bottom" content={<TopicList handleTopic={this.handleTopic.bind(this)} />} trigger="click">
<li style={sy2} onClick={this.handleBtn.bind(this,'topic')}>
<img alt='' src='//b-gold-cdn.xitu.io/v3/static/img/topic.6a87bb7.svg' />話題
</li>
</Popover>
</ul>
<Button type="primary" disabled={this.state.disabledBtn} onClick={this.handlePressEnter.bind(this)}>發佈</Button>
</div>
</div>
複製代碼
輸入框內容發生變化事件git
handelInputChange=(e)=>{
if(e.target.value.trim()!==''){
this.setState({
disabledBtn:false,
inputValue:e.target.value
})
}else{
this.setState({
disabledBtn:true
})
}
}
複製代碼
發佈按鈕事件github
handlePressEnter=()=>{
if(this.state.inputValue!==''){
console.log('發佈沸點')
}else{
message.error('請輸入沸點內容');
}
}
複製代碼
<div style={{background:'#fff'}}>
<Search
placeholder="搜索話題"
onSearch={value => this.handleSearch(value)}
style={{ width: '100%' }}
/>
<List
itemLayout="horizontal"
dataSource={this.state.topicListData}
style={{height:'300px',overflow:'auto'}}
renderItem={item => (
<List.Item style={{cursor:'pointer'}} onClick={this.handleClick.bind(this,item.title)}>
<List.Item.Meta
avatar={<Avatar size={42} shape="square" src={item.img} />}
title={item.title}
description={<div>{item.followers}關注 {item.num}沸點</div>}
/>
</List.Item>
)}
/>
</div>
複製代碼
搜索框回車搜索事件:數組
handleSearch=(value)=>{
const list=[...this.state.storeListData];
if(value!==''){
const searchList=list.filter(item=>item.title.indexOf(value)>-1);
this.setState({
topicListData:searchList
})
}else{
this.setState({
topicListData:list
})
}
}
複製代碼
話題列表點擊事件:bash
handleClick=(val)=>{
this.props.handleTopic(val);
}
複製代碼
這裏向父組件傳遞了一個val表明當前點擊話題,關於父子組件傳值的相關說明前面文章作了介紹,這裏再也不贅述。dom
render() {
const IconText = ({ type, text,tag }) => (
<span onClick={this.handleClick.bind(this,tag)}>
<Icon type={type} style={{ marginRight: 8 }} />
{text}
</span>
);
const PopoverContent=(id)=>{
return <p style={{cursor:'pointer'}} onClick={this.handleReport.bind(this,id)}>舉報</p>
}
return (
<div>
<List
itemLayout="vertical"
size="large"
dataSource={this.state.listData}
renderItem={item => (
<List.Item
key={item.author}
actions={
[
<IconText type="like" text={item.likeNum===0?'贊':item.likeNum} tag='like' />,
<IconText type="message" text={item.commentNum===0?'評論':item.commentNum} tag='comment' />,
<IconText type="share-alt" text="分享" tag='share' />
]
}
extra={
<div>
{!item.isFollowed && <Button style={{borderColor:'#6cbd45',color:'#6cbd45'}} onClick={()=>this.handleFollow(item.id)}>{item.isFollowed?'已關注':'關注'}</Button>}
<Popover placement="bottom" content={<PopoverContent author={item.author} />} trigger="click">
<span style={{cursor:'pointer',margin:'10px'}}>...</span>
</Popover>
</div>
}
>
<List.Item.Meta
// avatar={<Avatar size={45} src={item.avatar} />}
avatar={<Popover placement="top" content={<PersonalPop info={item} handleFollow={(id)=>this.handleFollow(id)} />}>
<Avatar size={45} src={item.avatar} />
</Popover>}
title={<Popover placement="top" content={<PersonalPop info={item} handleFollow={(id)=>this.handleFollow(id)} />}>
<span style={{cursor:'pointer'}}>{item.author}</span>
</Popover>}
description={<div><span>{item.description}</span><span style={{margin:'0 5px'}}>·</span><span>{timeUtil.getTimeAgo(item.editTime)}</span></div>}
/>
{item.content}
</List.Item>
)}
/>
</div>
);
}
複製代碼
用戶頭像鼠標滑過會出現詳情,使用了popover組件,具體內容是單獨抽離的一個PersonalPop組件。每一項根據isFollowed值判斷是否顯示關注按鈕,若是沒有關注,點擊可關注。ide
render() {
const { Meta } = Card;
return (
<div className='dynamicSide'>
<Card style={{ width: '100%' }} className='card1'>
<Meta
avatar={<Avatar size={62} src={this.props.userImage} />}
title={this.props.userId}
description={this.props.userDesc}
/>
<div>
<ul>
<li>
<p className='liTitle'>沸點</p>
<p className='liNum'>{this.state.userInfo.topNum}</p>
</li>
<li>
<p className='liTitle'>關注</p>
<p className='liNum'>{this.state.userInfo.following}</p>
</li>
<li>
<p className='liTitle'>關注者</p>
<p className='liNum'>{this.state.userInfo.follower}</p>
</li>
</ul>
</div>
</Card>
<Card
title="你可能感興趣的人"
style={{ width: '100%' ,marginTop:'10px'}}
className='card2'
>
<List
itemLayout="horizontal"
dataSource={this.state.interestList}
renderItem={item => (
<List.Item actions={[<Button>關注</Button>]}>
<List.Item.Meta
avatar={<Avatar size={40} src={item.userImage} />}
title={item.user}
description={item.desc}
/>
</List.Item>
)}
/>
<div className='user-recommend-footer' onClick={this.changeInterestList.bind(this)}>
<Icon type="sync" />換一批
</div>
</Card>
<div style={{marginTop:'10px'}}>
<TopicCard title='關注的話題' link='/topics' list={this.state.attentionTopic} />
</div>
<div style={{marginTop:'10px'}}>
<TopicCard title='更多話題' link='/topics' list={this.state.allTopic} />
</div>
</div>
);
}
複製代碼
鑑於關注的話題和更多話題內容結構相似,故抽離爲一個公用組件,且爲函數式組件。svg
function TopicCard({ title,list,link }){
return (
<Card
title={title}
extra={<a href={link} style={{color:'#007fff'}}>所有></a>}
style={{ width: '100%' }}
className='topicCard'
>
<List
itemLayout="horizontal"
dataSource={list}
renderItem={item => (
<List.Item>
<List.Item.Meta
avatar={<Avatar shape="square" size={40} src={item.userImage} />}
title={item.title}
description={<div style={{color:'#8a9aa9'}}><span>{item.followNum}關注</span>·<span>{item.hotNews}沸點</span></div>}
/>
</List.Item>
)}
/>
</Card>
);
}
複製代碼
React組件可分爲函數組件(Functional Component )和類組件(Class Component),劃分依據是根據組件的定義方式。函數組件使用函數定義組件,類組件使用ES6 class定義組件。函數
函數組件的寫法要比類組件簡潔,不過類組件比函數組件功能更強大。類組件能夠維護自身的狀態變量,即組件的state,類組件還有不一樣的生命週期方法,可讓咱們可以在組件的不一樣階段(掛載、更新、卸載)對組件作更多的控制,進行不一樣的操做。但函數組件的使用能夠從思想上讓你在設計組件時進行更多思考,更加關注邏輯控制和顯示的分離,設計出更加合理的組件結構。實際操做中,當一個組件不須要管理自身狀態時,能夠把它設計成函數組件,當你有足夠的理由發現它須要「升級」爲類組件時,再把它改造爲類組件。由於函數組件「升級」爲類組件是有必定成本的,這樣就會要求你作這個改造前更認真地思考其合理性,而不是僅僅爲了一時的方便就使用類組件。
function TopicItem({item,showCount}){
const {id,topicName,topicImage,topicCount,followedNum,topicNum,isFollowed}=item;
return (
<div className='topicItem'>
<Badge count={showCount?topicCount:0} overflowCount={999}>
<Avatar shape="square" size={72} src={topicImage} />
</Badge>
<div style={{marginLeft:'15px'}}>
<div>
<NavLink to={`/topic/${id}`}>{topicName}</NavLink>
</div>
<div style={{color:'#8a9aa9',marginTop:'5px'}}>
<span>{followedNum}關注</span>·
<span>{topicNum}沸點</span>
</div>
<div className={isFollowed?'hasFollowed':'noFollow'}>
{isFollowed?'已關注':'+關注'}
</div>
</div>
</div>
);
}
複製代碼
關注的話題數據實際上是所有話題的子集,在父頁面調用的時候根據數據中的isFollowed屬性進行一次篩選。
componentDidMount(){
const list=[...this.state.allTopicList];
const followedTopicList=list.filter(item=>item.isFollowed);
this.setState({
followedTopic:[...followedTopicList]
})
}
複製代碼
function TopNav({tags,changeLink}){
return (
<ul>
{tags.map((item,index)=>{
return <li key={item.path} onClick={()=>changeLink(item.path)}>
<NavLink to={`/books${item.path}`}>{item.text}</NavLink>
</li>
})}
</ul>
)
}
複製代碼
render() {
return (
<div>
<List
size="large"
bordered
dataSource={this.state.bookList}
renderItem={item => (
<List.Item className='bookList' onClick={()=>this.showInfo(item.bookId)}>
<img alt='books' src={item.img} />
<div>
<div style={{color:'#000',fontSize:'20px',fontWeight:400}}>
{item.isPresell && <span className="presale">預售</span> }
<span className='bookName'>{item.name}</span>
</div>
<div className='bookDesc'>{item.desc}</div>
<div className='bookAuthor'>
<NavLink to={`/user/:${item.userId}`}>
<Avatar size={26} src={item.userImage} />
<span style={{color:'#000',marginLeft:'5px'}}>{item.author}</span>
</NavLink>
<span style={{color:'#71777c',margin:'0 10px',whiteSpace:'nowrap',overflow:'hidden'}}>{item.selfDesc}</span>
</div>
<div className='other'>
{item.isBuy?<span className='bought'>已購買</span>:<span className='price'>¥{item.price}</span>}
<span className='message'>{item.chapterNum}小節</span>
{item.isBuy && <span className='message'>閱讀時長{item.readTime}分</span>}
<span className='message'>{item.purchaseNum}購買</span>
</div>
</div>
</List.Item>
)}
/>
</div>
);
}
複製代碼
會根據屬性是否預售isPresell和是否已經購買isBuy來判斷顯示不一樣內容。
相關詳細代碼可查看github,不要忘了star哦!工做中主要是以vue做爲主要技術棧,這是第一次使用React+React-router+Redux來構建項目,不足之處還請你們多多包涵。
金三已過,銀四會是什麼樣子呢?