13、React系列之 微博Demo 02 终结篇

版权声明:本文为博主原创文章,未经博主允许不得转载。

PS:转载请注明出处 作者:TigerChain 地址:http://www.jianshu.com/p/9fddf666b718 本文出自TigerChain简书

React 教程系列

教程简介

  • 1、阅读对象

本篇教程适合有React基础的朋友阅读(基础知道 state,props, 组件化思想,webpack+yarn 等),老鸟直接略过,如果有误,欢迎指出,谢谢。

正文

经过上一篇学习,我们把微博 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地址

github.com/githubchen0…

如果觉得对你有用,就点个喜欢吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值