使用React構建精簡版本掘金(二)

rocky191發表於2019-03-20

使用React構建精簡版本掘金(二)
咋一看,是不是感覺掘金改版了呢!如果你有這個錯覺,那就說明我仿照的還算可以,我就當是對我的肯定吧,O(∩_∩)O~~

首頁

頂部標籤

使用React構建精簡版本掘金(二)
即我上面紅框圈住的部分,這部分由於要做頁面滾動的時候常駐頂部,個人為了簡單省事,採用了ant-design中的Affix元件,另外導航元件我抽離了一個公用元件,從外部傳入tags陣列。

import { Affix} from 'antd';
...
this.state={
    tags:[
        {
            path:'recommended',
            text:'推薦'
        },
        {
            path:'following',
            text:'關注'
        }
    ]
}
...
<Affix offsetTop={this.state.top}>
    <div className="home-nav">
        <nav>
            <HomeNav tags={this.state.tags} match={match}/>
            <a href="/">標籤管理</a>
        </nav>
    </div>
</Affix>
複製程式碼

HomeNav元件如下

import React, { Component } from 'react';
import { NavLink } from 'react-router-dom'
...
class HomeNav extends Component {
    constructor(props) {
        super(props);
        this.state = {}
    }
    render() {
        return (
            <ul>
                {this.props.tags.map((item,index)=>{
                    return <li key={item.path}>
                        <NavLink to={`/timeline/${item.path}`}>{item.text}</NavLink>
                    </li>
                })}
            </ul>
        );
    }
}

export default HomeNav;
複製程式碼

動作部分

使用React構建精簡版本掘金(二)
該部分的實現方式可參考上面tag標籤實現部分,基本類似。
頭像部分我使用了ant-design中Avatar,用來代表使用者或事物,支援圖片、圖示或字元展示。

使用React構建精簡版本掘金(二)

文章列表部分

列表部分使用了ant-design中list元件

  • 列表結構實現
import { List,Statistic,Icon,Popover } from 'antd';
...
const {data}=this.props;
...
<List
    itemLayout="horizontal"
    dataSource={data}
    renderItem={item => (
    <List.Item extra={item.articleImage ? <img width={80} alt="logo" src={item.articleImage} />:''} onClick={this.showArticleInfo.bind(this,item.id)}>
        新增內容
    </List.Item>
    )}
/>
複製程式碼

實際中data應該是根據傳入的userID和標籤去資料庫查詢得到的真實資料,我這裡的data就從上一級中進行了獲取。每一個listItem上面繫結了點選事件,最終需要跳轉到文章詳情頁面。

  • 列表內部結構

使用React構建精簡版本掘金(二)
整體分成上中下三部分來實現佈局,右側的圖片是在上一步listItem中配置extra屬性可以實現。

<article>
    <section className="list-part1">
        <ul>
            <li className="item post">{item.articleType==='1'?'專欄':'小冊'}</li>
            <li>{item.author}</li>
            {item.time?<li>{item.time}</li>:''}
            {item.tags.length!==0?<li>{item.tags.map((tag,index)=>{
                return <NavLink key={tag} to={`/tag/${tag}`}>{tag}</NavLink>
            })}</li>:''}
        </ul>
    </section>
    <section className="list-part2">
        <NavLink to={`/post/:articleId`}>{item.title}</NavLink>
    </section>
    <section className="list-part3">
        {item.articleType==='1'?
            <div>
                <Statistic value={item.starNum} prefix={<Icon type="like" theme="filled" style={{ fontSize: '14px'}} />} onClick={()=>this.props.editStar(item.id)} />
                <Statistic value={item.commentNum} prefix={<Icon type="message" theme="filled" style={{ fontSize: '14px'}} onClick={()=>this.props.lookComment(item.id)} />} />
                <Icon type="upload" style={{ fontSize: '16px',marginLeft:'10px',borderRight:'none'}} />
                <Icon type="star" theme="filled" style={{ fontSize: '16px'}} onClick={()=>this.props.collectArticle(item.id)} />
            </div>:
            <div className="xiaoce-action-row">
                <span className="link-btn buy">購買人數: {item.sellNums}</span>
                <span className="link-btn sale">特價: {item.price}元</span>
                <span className="link-btn share">
                    <Icon type="upload" style={{ fontSize: '16px',marginLeft:'10px',borderRight:'none'}} onClick={()=>this.props.shareArticle(item.id)} />
                    分享
                </span>
            </div>
        }
    </section>
</article>
複製程式碼

掘金官網文章列表根據文章的型別是專欄還是小冊顯示不同的內容,即這裡根據item的articleType進行了區分,這裡用到了三目運算子做了顯示控制渲染。
React中條件渲染的方式有以下幾種,補充下知識點:
(1)if 語句
(2)三目操作符
(3)邏輯 && 操作符
(4)switch.. case.. 語句
(5)列舉
(6)多層條件渲染
(7)使用高階元件
詳情可查閱該文章

點選分享

  • 安裝qrcode.react外掛
yarn add qrcode.react --save
複製程式碼
  • 引入使用
const QRCode = require('qrcode.react');
...
<QRCode value={this.props.value} />
複製程式碼

value值是從上一級元件傳入的值,該外掛屬性描述:

prop type default value
value string -
renderAs string ('canvas' 'svg') 'canvas'
size number 128
bgColor string (CSS color) "#FFFFFF"
fgColor string (CSS color) "#000000"
level string ('L' 'M' 'Q' 'H') 'L'
includeMargin boolean false
  • 抽離分享元件
import React, { Component } from 'react';

class Qrcode extends Component {
    constructor(props) {
        super(props);
        this.state = {
            shareTypes:[
                {
                    image:'//b-gold-cdn.xitu.io/v3/static/img/weibo.8e2f5d6.svg',
                    text:'微博',
                    showQrcode:false,
                },
                {
                    image:'//b-gold-cdn.xitu.io/v3/static/img/wechat.844402c.svg',
                    text:'微信掃一掃',
                    showQrcode:true,
                }
            ]
        }
    }
    render() {
        const QRCode = require('qrcode.react');
        return (
            <ul>
                {this.state.shareTypes.map(item=>{
                    return <li key={item.text} style={{borderBottom:'1px solid rgba(217,222,224,.99)',padding:'10px',cursor:'pointer'}}>
                        <div>
                            <img alt={item.text} src={item.image} style={{width:'24px',height:'24px',marginRight:'5px'}} />
                            <label style={{color:'#8f969c'}}>{item.text}</label>
                        </div>
                        {item.showQrcode?<div style={{textAlign:'center'}}>
                            <QRCode value={this.props.value} />
                        </div>:''}
                    </li>
                })}
            </ul>
        );
    }
}

export default Qrcode;
複製程式碼
  • 分享元件使用
import Qrcode from '../../components/Qrcode';
...
<Popover content={<Qrcode value={window.location.href+'/'+item.id} />} placement="bottom" trigger="click">
    <Icon type="upload" style={{ fontSize: '16px',marginLeft:'10px',borderRight:'none'}} onClick={()=>this.props.shareArticle(item.id)} />
    分享
</Popover>
複製程式碼

右側卡片內容

這塊內容採用了ant-design中的card元件,直接看程式碼吧。

import { Card } from 'antd';
...
<Card
    title="掘金優秀作者"
    style={{ width: '100%' }}
    hoverable={'true'}
    actions={[<NavLink to='/recommendation/authors/recommended' style={{color:'#007fff'}}>檢視更多></NavLink>]}
    >
    <List
        itemLayout="horizontal"
        dataSource={this.props.goodAuthor}
        renderItem={item => (
        <List.Item onClick={()=>window.location.href='/user/'+item.id}>
            <List.Item.Meta
            avatar={<Avatar size={46} src={item.userImage} />}
            title={item.title}
            description={<div className="overflow-ellipsis">{item.desc}</div>}
            />
        </List.Item>
        )}
    />
</Card>
複製程式碼

goodAuthor資料是從父級傳入的資料哈。

使用React構建精簡版本掘金(二)
這裡的內容結構類似,外層card元件,內建不同不同內容,就不重複了,想看具體實現的話請移步github,不要忘了star哈。

card內部使用list元件,豎著排列各自的內容,這一塊總覺得可以抽成一個公用的card元件,然後填充不同內容,暫時就先這樣吧,列入後期重構計劃!這時就懷念vue中的slot方法了,可以方便的放置不同內容。jsx也有自己的方便之處吧,靈活的使用各種標籤。

以上就是首頁的一個簡單說明了,頁面大部分的連結router跳轉功能還沒有實現,後續陸續更新中。

想看第一篇文章的朋友可以檢視使用React構建精簡版本掘金(一),上述所有詳細程式碼都已經放到github了,歡迎瀏覽和star哈,都已經看到這裡了,那就麻煩大家點個贊在走吧!

既然沒有合適的坑,那就趁著閒暇,繼續提升自己的能力吧!最後鼓勵下自己:扛過了艱難的時光,回頭看,那也就不是什麼大不了的事情了!

相關文章