版權聲明:本文為博主原創文章,未經博主允許不得轉載。
PS:轉載請注明出處
作者:TigerChain
地址:http://www.lxweimin.com/p/9fddf666b718
本文出自TigerChain簡書
教程簡介
- 1、閱讀對象
本篇教程適合有React基礎的朋友閱讀(基礎知道 state,props, 組件化思想,webpack+yarn 等),老鳥直接略過,如果有誤,歡迎指出,謝謝。
-
2、教程難度
中級
3、Demo 地址
https://github.com/tigerchain/react-lesson/tree/master/lesson02/10-weibodemo
正文
經過上一篇學習,我們把微博 Demo 的雛形搭建出來了,那把接下來我們把微博后面的內容帶大家手把手全部做完。我們接著上一節的步驟繼續學習
5、添加頭像組件
- 1、在項目的根目錄新建 img 文件夾并且放入三張圖片 (具體在demo中去查看)
- 2、修改 WeiBoListItem.js
只添加一句代碼,就是進入一張圖片并且設置樣式,這里就不貼代碼了,看圖即可。
如圖所示,其中黃色部分就是我們引入一張圖片,并設置樣式,大家應該想到了還要去設置樣式,沒錯。
- 3、修改 ListItemStyle.css ,添加以下樣式即可
.imgStyle{
width: 80px;
height: 80px;
border-radius: 40px;
margin-right: 10px;
}
- 4、yarn start 跑一下,如果沒有什么問題,會報如下錯
從圖中我們可以清楚的看到報錯的原因,就是我們加載不了圖片,給我們的建議是下面這條紅線中說的,我們需要 loader 去處理文件類型。loader 我們不陌生,我們去安裝即可。提前說一下,在這里我們要安裝兩個 loader 分別是 url-loader 和 file-loader (都是用于打包文件和圖片)。關于 url-loader 和 file-loader 的區別 請查看:url-loader和file-loader加載器有什么區別?
- 5、安裝 url-loader 和 file-loader。
yarn add url-loader file-loader --dev
安裝了 loader 以后肯定要在 webpack.config.js 中去配置。
- 6、添加 url-loader file-loader 到 webpack.config.js 中去
{
test: /\.(png|jpg)$/,
loader: 'url-loader?limit=8192'
}
將以上內容添加到 webpack.config.js loaders 標簽中,這沒什么好說的。
- 7、運行項目 yart-start
我們就會看到如下界面
我們如期把頭像加載進來了。
6、添加評論列表組件
我們在項目 app 目錄新建 評論組件 CommentForm.js
# CommentForm.js
import React, { Component, PropTypes } from 'react';
// 導入評論的樣式
import styles from '../css/commentStyle.css';
/**
* 取得當前時間
* @return {[type]} [description]
*/
function getCurrentFormatDate() {
var date = new Date() ;
var seperator1 = "-" ;
var seperator2 = ":" ;
var month = date.getMonth() + 1 ;
var strDate = date.getDate() ;
if (month >= 1 && month <= 9) {
month = "0" + month;
}
if (strDate >= 0 && strDate <= 9) {
strDate = "0" + strDate;
}
var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate
+ " " + date.getHours() + seperator2 + date.getMinutes()
+ seperator2 + date.getSeconds();
return currentdate;
}
/**
* 評論組件
*/
export default class CommentForm extends Component {
constructor(props) {
super(props);
this.state = {
//默認回復內容為空
replycontents:[],
}
}
render() {
//遍歷評論內容
var replyContentDatas = this.state.replycontents.map(function(data,index) {
return(
// <CommentReplyList key={index} reply={data}/>
<div key={index}>
<div>
{/* 回復姓名 */}
<span>{data.name}</span>
{/* 回復內容 */}
<span>{data.content}</span>
</div>
{/* 回復時間 */}
<span>{data.time}</span>
</div>
);
});
return (
<div className={styles.rootView}>
<div className={styles.headView}>
{/* 回復的頭像 */}
<img src={require('../img/qiche.jpg')} className={styles.img} />
{/* 回復的文本框 */}
<div className={styles.textareaViewStyle}>
<textarea cols='4' rows='4' ref="content"/>
<button className={styles.commentBtnStyle} onClick={this._reply.bind(this)}>評論</button>
</div>
</div>
{/* 回復內容 */}
{replyContentDatas}
</div>
);
}
/**
* 回復評論功能
*/
_reply(){
//取得當前時間
let currentTime = getCurrentFormatDate();
//取得回復的內容
let recontent = this.refs.content.value;
if(recontent.length==0){
alert('評論內容不能為空!')
return ;
}
let newContent = {
content:recontent,
name:'軍軍',
time:currentTime,
}
//取得老的回復內容
let oldRepContent = this.state.replycontents,
//新的回復內容和老的回復內容疊加起來
newRplContent = oldRepContent.concat(newContent);//數組的疊加
//
this.setState({
replycontents:newRplContent,
});
//輕空輸入框內容
this.refs.content.value = "";
}
}
這個代碼稍微有點多,但是注釋寫的非常清楚,此組件的作用就是把評論的組件寫出來。
7、在 css 目錄中新建 commentStyle.css (評論組件 css 樣式)
/*根樣式*/
.rootView{
display: flex;
flex-direction: column;
background: #fff;
padding: 10px;
margin-top: -15px;
}
/*評論頭頭像,文本框,按鈕樣式*/
.headView{
display: flex;
background: #fff;
}
/*昵稱樣式*/
.nickNameStyle{
display: flex;
flex-direction: column;
font-size: 12px;
}
/**
* 評論列表樣式
*/
.commentListStyle{
padding-left: 55px;
margin-bottom: 10px;
display: flex;
align-items: flex-start;
}
/**
* 評論內容樣式
*/
.commentContentStyle{
display: flex;
flex:1;
margin-left: 10px;
justify-content: space-between;
}
.img{
width: 35px;
height: 35px;
}
/**
* 評論內容樣式
*/
.textareaViewStyle{
margin-left: 20px;
display: flex;
flex-direction: column;
flex:1;
margin-bottom: 10px;
}
/**
* 評論按鈕樣式
*/
.commentBtnStyle{
width: 100px;
background: #ff8146;
margin-top: 10px;
border: 1px solid #f77c3d;
color: #fff;
height: 25px;
font-size: 14px;
}
這沒有什么好說的,經過前面一步步的創建 css 這里我們大體也能看懂,注釋也非常清楚。
以上步驟我們就成功創建了個評論組件,但是我們要把這個組件嵌入到 WeiBoListItem.js 中并且添加事件交互,我們接著做
8、添加 CommentForm.js 到 WeiBoListItem.js 中
- 1、首先我們在 WeiBoListItem.js 中導入評論組件
# WeiBoListItem.js
import CommentForm from './CommentForm' ;
- 2、在 render 的 return 方法中隱藏或顯示評論組件
# WeiBoListItem.js
//渲染界面
render() {
let data = this.props.itemData ;
return (
<div>
{this._renderHeadView(data)}
<hr className={styles.hrStyle}/>
{this._renderFooterView(data)}
{/* 點擊評論按鈕 則展開評論組件,否則隱藏 新添加的方法*/}
{this.state.isComment? <CommentForm />:null}
</div>
);
}
- 3、給點贊等按鈕添加事件在 _renderFooterView() 方法中
# WeiBoListItem.js
_renderFooterView(data){
return(
<div className={styles.commentViewStyle}>
<ul className={styles.ulStyle}>
{/* 此處新增方法 */}
<li className={styles.liStyle} onClick={this._dianzan.bind(this)}>點贊:{this.state.zanNum}</li><div className={styles.shuxian}></div>
<li className={styles.liStyle} onClick={this._comment.bind(this)}>評論:{data.NoComment}</li><div className={styles.shuxian}></div>
<li className={styles.liStyle} onClick={this._zhuanFa.bind(this)}>轉發:{data.NoPointGreat}</li>
</ul>
</div>
);
}
4、添加點贊等方法
# WeiBoListItem.js
/**
* 評論方法
*/
_comment(){
this.setState({
isComment:true
})
}
/**
* 點贊方法
*/
_dianzan(){
this.setState({
isComment:false,
zanNum:parseInt(this.state.zanNum)+1,
})
}
/**
* 轉發方法
*/
_zhuanFa(){
this.setState({
isComment:false
})
}
到這里基本上我就能響應評論組件并且輸入內容來交互了,試一下吧。在命令行中 使用 yarn start ,并在瀏覽器輸入 localhost:8899 回車
我們基本上把開頭微博的樣子完成百分之九十了,接下來就是把評論組件抽取出來并且把評論列表樣式修改一下(我們這里只是把姓名,內容,時間顯示出來,這里完全可以抽取成一個組件)
9、抽取評論列表
在 app 中新建 CommentReplyList.js (評論列表組件)
# CommentReplyList.js
import React, { Component, PropTypes } from 'react';
import styles from '../css/commentStyle.css';
/**
* 評論列表組件
*/
export default class CommentReplyList extends Component {
constructor(props) {
super(props);
this.state = {
// 回復列表
data:this.props.reply
}
}
render() {
let replyContent = this.state.data ;
return (
<div className={styles.commentListStyle}>
<img src={require('../img/avtova.jpg')} className={styles.img} />
{/**評論布局**/}
<div className={styles.commentContentStyle}>
{/**昵稱和內容布局**/}
<div className={styles.nickNameStyle}>
{/**評論昵稱**/}
<span>{replyContent.name}</span>
{/**評論內容**/}
<span>{replyContent.content}</span>
</div>
{/**評論時間**/}
<span className={styles.timeSize}>{replyContent.time}</span>
</div>
</div>
);
}
}
10、修改 CommentForm.js
從圖中可以看到,我們只是修改黃色部分即可。
看一下效果:
我們可以看到評論列表樣式我們修改完成了。
11、添加微博列表中圖片組件
- 1、在 app 中新建 CommentListImgs.js (微博列表圖片組件)
import React, { Component, PropTypes } from 'react';
/**
* 導入圖片樣式
*/
import styles from '../css/commentImgsStyle.css' ;
/**
* 微博列表中的圖片 無狀態的組件
*/
export default class CommentListImgs extends Component {
constructor(props) {
super(props);
}
render() {
// 遍歷圖片并顯示
var imgs = this.props.imgUrls.map(function(imgurl,index) {
return(<li key={index} className={styles.liStyle}><img src={require('../img/avtova.jpg')} className={styles.imgStyle}></img></li>);
});
return(
<ul className={styles.ulstyle}>
{imgs}
</ul>
) ;
}
}
- 2、添加圖片組件樣式
在 css 目錄中新建 commentImgsStyle.css 并輸入以下內容
.imgStyle{
width: 100px;
height: 100px;
}
.ulstyle{
margin-top: 0px;
display: flex;
flex-wrap: wrap;
padding-left: 0px;
}
.liStyle{
list-style:none;
float:left;
margin-right: 10px;
margin-top: 10px;
align-self: center;
}
- 3 、修改 WeiBoListItem.js 組件 以下核心修改的地方
import CommentListImgs from './CommentListImgs.js' ;
_renderHeadView(data){
return(
<div className={styles.item}>
<img src={require('../img/tiger.jpg')} className={styles.imgStyle}></img>
<div className={styles.topRightView}>
<div className={styles.nickNameAndSendTime}>
<span>{data.nickName}</span>
<span>{data.sendTime}</span>
</div>
<p>{data.content}</p>
{/**新添加的內容**/}
{data.contentImgUrls?<CommentListImgs imgUrls={data.contentImgUrls}/>:null}
</div>
</div>
)
}
代碼太多,我們這里只貼出核心修改的地方,具體代碼看demo
我們再運行一下,就會看到我們開頭的效果圖
到此為止,我們手把手教大家擼了一個微博的小 Demo,經過這個 demo 大家掌握 webpack+yarn+react的基礎知識,以及組件化的思想,無狀態化組件編寫等。希望大家能從 0 開始動手寫一遍。
Demo地址
https://github.com/tigerchain/react-lesson/tree/master/lesson02/10-weibodemo
如果覺得對你有用,就點個喜歡吧。