12、React系列之--微博 Demo 01

版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。

PS:轉(zhuǎn)載請(qǐng)注明出處
作者:TigerChain
地址:http://www.lxweimin.com/p/f4e6ecfd52fd
本文出自TigerChain簡(jiǎn)書

React 教程系列

教程簡(jiǎn)介

  • 1、閱讀對(duì)象

本篇教程適合有React基礎(chǔ)的朋友閱讀(基礎(chǔ)知道 state,props, 組件化思想,webpack+yarn 等),老鳥(niǎo)直接略過(guò),如果有誤,歡迎指出,謝謝。

React 系列之--微博 Demo 02 終結(jié)篇:http://www.lxweimin.com/p/9fddf666b718

正文

經(jīng)過(guò)前面幾個(gè)章節(jié)的學(xué)習(xí),我們基本上把 React 的一些基本知識(shí)掌握了,那么我們把以前掌握的知識(shí)綜合起來(lái)做一個(gè)小案例。來(lái)對(duì)前面知識(shí)做一個(gè)歸納和復(fù)習(xí),本節(jié)知識(shí)需要前面知識(shí)學(xué)習(xí),如果沒(méi)有學(xué)習(xí),建議先去學(xué)習(xí)前面的章節(jié)比如 webpak yarn babel等。

1、無(wú)圖無(wú)真相,效果圖

weibo-demo.gif

如圖所示,今天要寫的 Demo 就長(zhǎng)上面的樣子

2、可以學(xué)到什么

通過(guò)本 Demo 我們可以學(xué)習(xí)到組件的組合,內(nèi)聯(lián) css 樣式使用,flexbox布局,組件化思想以及組件之間的交互等內(nèi)容。

3、Demo分析

首先我們把微博組件化,如何劃分組件呢,我們以下圖為劃分組件的標(biāo)準(zhǔn),當(dāng)然這不是唯一標(biāo)準(zhǔn),只是我覺(jué)得比較好的組件分的方式。

weibo-component.png

4、開(kāi)始擼碼

1、微博的雛形

接下來(lái)我們就手把手從0開(kāi)始開(kāi)發(fā)微博 demo,我們使用 webpack+yarn 來(lái)構(gòu)建項(xiàng)目,在 mac 環(huán)境下(由于本人電腦是 mac ),win 下基本差不多.

1、進(jìn)入命令行在指定目錄中新建 weibodemo

mkdir weibodemo

2、使用 yarn 初始化項(xiàng)目

yarn-init.png

3、添加依賴

yarn add babel-core babel-loader babel-preset-es2015 babel-preset-react babel-preset-stage-0  react react-dom webpack webpack-dev-server --dev

經(jīng)過(guò)前面幾節(jié)的學(xué)習(xí),我們都知道安裝這些依賴是什么意思,這里不再多說(shuō),如果明折,可以看 webpack 這節(jié)http://www.lxweimin.com/p/732c4d501668

通過(guò)以上操作,如果沒(méi)有什么問(wèn)題,就會(huì)把所需要的依賴添加進(jìn)去了。

weibo-adddepend.png

4、在項(xiàng)目根目錄新建 .babelrc 并輸入以下內(nèi)容

{
  "presets": ["react", "es2015","stage-0"]
}

5、在項(xiàng)目根目錄中新建 webpack.config.js 并配置

module.exports = {
  entry:  __dirname + "/app/main.js",
  output: {
    path: __dirname + "/public",
    filename: "bundle.js"
  },
  module: {
    loaders: [
      //babel配置
    {
      test:/\.js$/,
      exclude: /node_modules/,
      loader: 'babel-loader'
    }
    ]
  },

  devServer:{
    contentBase: "./public",//本地服務(wù)器所加載的頁(yè)面所在的目錄
    // colors: true,//終端中輸出結(jié)果為彩色
    historyApiFallback: true,//不跳轉(zhuǎn)
    inline: true//實(shí)時(shí)刷新
  }
}

6、在根目錄中新建 public 和 app 目錄,并且分別新建index.html 和 ?main.js

#  index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>WeiBo demo</title>
</head>
<body>
<div id="container"></div>
<script src='bundle.js'></script>
</body>
</html>

#  main.js

import React from 'react' ;
import ReactDOM from 'react-dom' ;

//模擬微博列表數(shù)據(jù)
var datas = {
  "data":[
    {
        "myUrl":"../img/tiger.jpg",
        "headUrl":"../img/tiger.jpg",
        "nickName":"小東",
        "content":"今天天氣不錯(cuò)呀,我可以好好的出去玩玩了!!!",
        "NoCollect":"13",
        "NoForward":"20",
        "NoComment":"14",
        "NoPointGreat":"42",
        "sendTime":"11月10日"
    },
    {
        "myUrl":"../img/tiger.jpg",
        "headUrl":"../img/tiger.jpg",
        "nickName":"小高",
        "content":"今天去了了家新開(kāi)的超市,里面東西真多呀",
        "NoCollect":"12",
        "NoForward":"2",
        "NoComment":"12",
        "NoPointGreat":"23",
        "sendTime":"10月8日",
        "contentImgUrls":[
            {"img":"../img/qiche.jpg"},
            {"img":"./img/qiche.jpg"},
            {"img":"../img/qiche.jpg"},
            {"img":"./img/qiche.jpg"}
        ]
    },
    {
        "myUrl":"../img/me.png",
        "headUrl":"../img/ruobin.png",
        "nickName":"Michelle不想讓人看見(jiàn)",
        "content":"看了一部電視,感覺(jué)非學(xué)不錯(cuò),給大家推薦一下",
        "NoCollect":"132",
        "NoForward":"202",
        "NoComment":"142",
        "NoPointGreat":"423",
            "sendTime":"11月6日"
    }
  ]
  }

//定義微博列表組件
 class WeiboList extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    //遍歷微博列表
    var ItemView = datas.data.map(function(item,index) {
    return (<div key={index}>
      {item.nickName} <br/>
        
      {item.content}
      <hr />
    </div>) ;
    //渲染列表
    return (<div>{ItemView}</div>);
  }
}


ReactDOM.render(
 <WeiboList />,
  document.getElementById('container')
) ;

接下來(lái)我們?cè)?package.json 中配置腳本

"scripts":{
    "start":"webpack-dev-server --progress --port 8899"
}

從上面的代碼我們可以知道,我們創(chuàng)建一個(gè)微博列表組件,然后渲染在界面上,并且我們模擬了一些微博列表的數(shù)據(jù),那么我們看看效果:

在命令行中輸入 yarn start,此過(guò)程如果沒(méi)有什么問(wèn)題,我們?cè)跒g覽器輸入 loaclhost:8899 會(huì)看到以下效果:

weibo-first.png

從圖中我們可以看到微博的雛形出來(lái)了。

2、樣式和組件化微博

通過(guò)上面我們知道,我們把微博列表和數(shù)據(jù)都寫在同一個(gè)界面中了,React 玩的就是組件化,所以我們接下來(lái)把微博列表定義成一個(gè)組件并且把數(shù)據(jù)抽出來(lái)。以下步驟都是在上面 demo 的基礎(chǔ)上去改的。

1、在 app 目錄中新建一個(gè) WeiBoList.js

# WeiBoList.js

import React, { Component, PropTypes } from 'react';

//定義一個(gè)微博列表組件
export default class WeiBoList extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    //遍歷微博列表
    var ItemView = datas.data.map(function(item,index) {
    return (<div key={index}>
      {/* 昵稱 */}
      {item.nickName}
    <br />
      {/* 內(nèi)容 */}
      {item.content}
        <hr />
    </div>)
  }) ;
    //渲染列表
    return (<div>{ItemView}</div>);
  }
}

WeiBoList.propTypes = {
};

2、將數(shù)據(jù)抽取在 json 文件件中

在 weibodemo 根目錄中新建 data/data.json 文件

{"data":[
    {
        "myUrl":"../img/tiger.jpg",
        "headUrl":"../img/tiger.jpg",
        "nickName":"小東",
        "content":"今天天氣不錯(cuò)呀,我可以好好的出去玩玩了!!!",
        "NoCollect":"13",
        "NoForward":"20",
        "NoComment":"14",
        "NoPointGreat":"42",
        "sendTime":"11月10日"
    },
    {
        "myUrl":"../img/tiger.jpg",
        "headUrl":"../img/tiger.jpg",
        "nickName":"小高",
        "content":"今天去了了家新開(kāi)的超市,里面東西真多呀",
        "NoCollect":"12",
        "NoForward":"2",
        "NoComment":"12",
        "NoPointGreat":"23",
        "sendTime":"10月8日",
        "contentImgUrls":[
            {"img":"../img/qiche.jpg"},
            {"img":"./img/qiche.jpg"},
            {"img":"../img/qiche.jpg"},
            {"img":"./img/qiche.jpg"}
        ]
    }
    
    ]
}


PS:這里我為了說(shuō)明,json 微博列表數(shù)據(jù)給出了兩個(gè),實(shí)際以 demo 中為準(zhǔn),或者自行添加。

3、修改 main.js

# main.js

import React from 'react' ;
import ReactDOM from 'react-dom' ;
//引入微博列表組件
import WeiBoList from './WeiBoList.js' ;
//導(dǎo)入數(shù)據(jù)
import datas from '../data/data.json' ;

//渲染微博列表 并且把數(shù)據(jù) 通過(guò)props傳遞到 WeiBoList中
ReactDOM.render(
 <WeiBoList data={datas.data}/>,
  document.getElementById('container')
) ;

我們可以看到 main.js 我們修改的還是比較大的,把模擬數(shù)據(jù)和微博組件都從 main.js 中移除了,并且導(dǎo)入數(shù)據(jù)和微博列表組件( WeiBoList ),并且以 props 形式把數(shù)據(jù)傳遞給 WeiBoList 組件

4、再次修改 WeiBoList.js

我們使用 props 屬性拿到微博列表數(shù)據(jù)然后遍歷,所以這里有一點(diǎn)小修改,代碼就不貼出來(lái)了,直接上個(gè)圖吧。

weibolist-props.png

其中黃色的部分就是我們修改過(guò)的。

5、 運(yùn)行看效果,如果沒(méi)有什么問(wèn)題則會(huì)顯示如下:

weibo-second.png

我們成功以的把數(shù)據(jù)抽取出來(lái),并且邁開(kāi)了組件人的第一步。

6、引入 css 樣式

以上我們都是在進(jìn)行無(wú)樣式開(kāi)發(fā),現(xiàn)在我們就引用 flexbox 和 css 給界面添加一些色彩。

  • 1、在項(xiàng)目根目錄添加 css/ListStyle.css
.listRootViewStyle {
  background-color: #eee; /**背景色*/
  padding: 10px;  /**設(shè)置內(nèi)邊距**/
}
  • 2、修改WeiBoList.js
modify-weibolist.png

其中黃色的部分是我們新添加的。

  • 3、我們添加 style-loader css-loader

如果完成上面的部分,那還沒(méi)有完,我們必須添加 style-loader css-loader 否則 2 中的修改會(huì)報(bào)錯(cuò)。

yarn add style-loader css-loader --dev

PS:其中 css-loader 是用來(lái)讀取 css 文件的
style-loader 將css插入到頁(yè)面中

我們運(yùn)行一下項(xiàng)目,不出什么問(wèn)題會(huì)報(bào)如下錯(cuò)

not-config-css-loader.png

這是什么原因呢,看過(guò)webpack這一章的朋友應(yīng)該知道我們安裝一個(gè) loader 就要在 webpack.config.js 中去配置。

接下來(lái)我們?cè)?webpack.config.js 中去配置 css-loader 和 style-loader 。

add-css-loader.png

從圖中可知我們添加了黃色部分

#  style-loader css-loader

{
    test: /\.css$/,
    loader: 'style-loader!css-loader?modules'
}

7、運(yùn)行一下看效果

weibo-bgstyle.png

我們看到 css 樣式成功表現(xiàn)在微博上了。

3、完善微博列表

上面我們給微博添加了樣式,但是這看起來(lái)還不是很舒心,我們把微博列表抽成一個(gè)組件,如下:

weibo-footview.png

由圖可以知道,這個(gè)組件基本上是上下分隔的,以分隔線為主。可以做成兩個(gè) view ,當(dāng)然也可以自定義成兩個(gè)組件。我們這里就分成圖片列表組件 CommentListImgs.js 評(píng)論組件 CommentForm.js 和微博列表組件 WeiBoListItem.js,我們一步一步來(lái),先做 WeiBoListItem.js,后面再一步步的添加 CommentForm.js 和 CommentListImgs.js

以下功能都是在上面的基礎(chǔ)上完成的。

1、在app中新建 WeiBoListItem.js 組件

import React, { Component, PropTypes } from 'react';

import styles from '../css/ListItemStyle.css' ;

/**
 * 微博評(píng)論列表組件
 */
export default class WeiBoListItem extends Component {
  constructor(props) {
    super(props);
    this.state = {
      //是否點(diǎn)擊評(píng)論按鈕標(biāo)志
      isComment:false,
      //默認(rèn)的條目數(shù)據(jù)
      itemData:this.props.itemData,
      //默認(rèn)的點(diǎn)贊數(shù)
      zanNum:this.props.itemData.NoCollect
    }
  }

  render() {
    //取得傳遞過(guò)來(lái)的數(shù)據(jù)
    let data = this.props.itemData ;


    return (
      <div>
          {this._renderHeadView(data)}

          <hr className={styles.hrStyle}/>

          {this._renderFooterView(data)}
          
        </div>
     );
  }

  /**
   * 渲染頂部View
   */
  _renderHeadView(data){
    return(
      <div className={styles.item}>
     
     
        <div className={styles.topRightView}>
          <div className={styles.nickNameAndSendTime}>
            <span>{data.nickName}</span>
            <span>{data.sendTime}</span>
          </div>
          
          <p>{data.content}</p>
        </div>
      </div>
    )
  }

  /**
   * 渲染底部View
   */
   _renderFooterView(data){
       return(
         <div className={styles.commentViewStyle}>
           <ul className={styles.ulStyle}>
             <li className={styles.liStyle} >點(diǎn)贊:{this.state.zanNum}</li><div className={styles.shuxian}></div>
             <li className={styles.liStyle} >評(píng)論:{data.NoComment}</li><div className={styles.shuxian}></div>
             <li className={styles.liStyle} >轉(zhuǎn)發(fā):{data.NoPointGreat}</li>
           </ul>
         </div>
       );
   }
 }

2、在 css 目錄中新建 ListItemStyle.css


.item{
  display: flex;
  background-color: #fff;
  padding: 20px;
}
/*頂部view樣式*/
.topRightView{
  display: flex;
  flex-direction: column;
  flex:1
}
/*昵稱和發(fā)送時(shí)間樣式*/
.nickNameAndSendTime{
  display: flex;
  justify-content: space-between; /**主軸的對(duì)齊方式*/
}


/*橫線樣式*/
.hrStyle{
  margin-top: -1px;
}
.ulStyle{
  display:flex;
  height: 40px;
  align-items: center;
  margin-left: -40px;
}
/*點(diǎn)贊 轉(zhuǎn)發(fā)*/
.liStyle{
  display: flex;
  color: orange;
  flex: 1.0;
  font-size: 16px;
  justify-content: center;
}
.commentViewStyle{
  background-color: #fff;
  margin-top: -17px;
}

.shuxian{
  height: 20px;
  width: 1px;
  background-color: grey;
}

3、修改WeiBoList.js

modify-weibolist2.png

如圖所示:我們修改的部分為黃色部分,最終WeiBoList.js為


import React, { Component, PropTypes } from 'react';

import styles from '../css/ListStyle.css' ;

//導(dǎo)入微博列表組件
import WeiBoListItem from './WeiBoListItem.js'

//定義一個(gè)微博列表組件
export default class WeiBoList extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    //遍歷渲染每個(gè)條目
    var ItemView = this.props.data.map(function(item,index) {
      return <WeiBoListItem itemData= {item} key = {index}/>
    }) ;

    return(
      <div className={styles.listRootViewStyle}>
       {ItemView}
      </div>
    ) ;
}
}

WeiBoList.propTypes = {
};

4、運(yùn)行看效果,就會(huì)看到我上面的效果圖

component-weibo-1.gif

到此為止,我們就把微博的基本雛形搞出來(lái)了,下一節(jié)我們把評(píng)論組件和頭像等做出來(lái),并且添加事件交互 。

Demo地址

https://github.com/tigerchain/react-lesson/tree/master/lesson02/10-weibodemo

在React 系列之--微博 Demo 02 終結(jié)篇中我們會(huì)繼續(xù)本篇來(lái)完成最終的效果。以下終結(jié)篇的地址。

React 系列之--微博 Demo 02 終結(jié)篇:http://www.lxweimin.com/p/9fddf666b718

如果覺(jué)得對(duì)你有用,就點(diǎn)個(gè)喜歡吧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,701評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 178,691評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 63,974評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,694評(píng)論 6 413
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 56,026評(píng)論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評(píng)論 3 450
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 43,193評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,719評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,668評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,846評(píng)論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 35,255評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 36,592評(píng)論 1 295
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,394評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,635評(píng)論 2 380

推薦閱讀更多精彩內(nèi)容

  • 版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。 PS:轉(zhuǎn)載請(qǐng)注明出處作者:TigerChain地址:http...
    TigerChain閱讀 1,403評(píng)論 3 4
  • 無(wú)意中看到zhangwnag大佬分享的webpack教程感覺(jué)受益匪淺,特此分享以備自己日后查看,也希望更多的人看到...
    小小字符閱讀 8,220評(píng)論 7 35
  • GitChat技術(shù)雜談 前言 本文較長(zhǎng),為了節(jié)省你的閱讀時(shí)間,在文前列寫作思路如下: 什么是 webpack,它要...
    蕭玄辭閱讀 12,710評(píng)論 7 110
  • 構(gòu)建一個(gè)小項(xiàng)目——FlyBird,學(xué)習(xí)webpack和react。(本文成文于2017/2/25) 從webpac...
    布蕾布蕾閱讀 16,854評(píng)論 31 98
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,771評(píng)論 25 708