1 React中使用路由

1.1 安装

yarn add react-router-dom

import { BrowserHistory, Route} from 'react-router-dom';

1.2 路由设置和使用

打开我们的APP.js,如下是设置的代码

代码解释:

import { BrowserRouter, Route} from 'react-router-dom'; 导入模块,外面加一层div 是有要去的 render只包含一个child

添加路由:

home
}>

detail
}>

path: 路径

其中exact表示只有路径完全匹配才能访问(如果不设置的话,/detail的路径两个都可以访问到)

src/App.js

import React, { Component} from 'react';

import Header from './common/header'

import { BrowserRouter, Route} from 'react-router-dom';

import store from './store'

import { Provider } from 'react-redux';

class App extends Component {

render() {

return (

home
}>

detail
}>

);

}

}

export default App;

2 首页组件的拆分

组件拆分原则:

组件拆分是为了我们更加容易的管理各个组件。因此在拆分的时候我们要进行一个合理拆分,使得我们的代码更简洁,更的容易维护

我们将上图分为 5 个区域,其中图片的显示很简单,我们就将它放在首页,index中,其它的放在conponents中进行管理

代码模板:

import React, {Component} from 'react';

class Lsit extends Component {

render() {

return (

Lsit

)

}

}

export default Lsit;

App.js

import React, { Component} from 'react';

import Header from './common/header'

import { BrowserRouter, Route} from 'react-router-dom';

import Home from './pages/home';

import Detail from './pages/detail';

import store from './store'

import { Provider } from 'react-redux';

class App extends Component {

render() {

return (

);

}

}

export default App;

index.js

import React, {Component} from 'react';

import Topic from './components/Topic';

import List from './components/List';

import Writer from './components/Writer';

import Recommend from './components/Recommend';

import {

HomeWrapper,

HomeLeft,

HomeRight

} from './style';

class Home extends Component {

render() {

return (

react.js 简书项目实战-main首页开发  第1张

)

}

}

export default Home;

3 首页专题布局及reducer设计

3.1 布局

我们设置布局,同时调整样式,样式都在style.css进行

import React, {Component} from 'react';

import {

TopicWrapper,

TopicItem

} from '../style';

class Topic extends Component {

render() {

return (

className='topic-pic'

src='https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1074417518,1198280004&fm=26&gp=0.jpg' alt='tu'

/>

社会热点

)

}

}

export default Topic;

Topic的样式

export const TopicItem = styled.div`

float: left;

height: 32px;

line-height: 32px;

margin-left: 18px;

margin-bottom: 18px;

padding-right: 10px;

font-size: 14px;

background: #f7f7f7;

color: #000;

border: 1px solid #dcdcdc;

border-radius: 4px;

.topic-pic {

margin-right: 10px;

display: block;

float: left;

width: 32px;

height:32px;

}

`

3.2 reducer设计

首先我们在home目录下,创建一个reducer和index,用index导出reducer,另外在reducer中存放我们需要的数据

如下:

(1)home/reducer

存放数据

import { fromJS } from 'immutable';

//将其变为immutable

const defaultState = fromJS({

topicList: [{

id: 1,

title: '社会热点',

imgUrl: '//upload.jianshu.io/collections/images/261938/man-hands-reading-boy-large.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/64/h/64'

},{

id:2,

title: '手绘',

imgUrl: '//upload.jianshu.io/collections/images/21/20120316041115481.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/64/h/64'

}]

});

export default (state = defaultState, action) => {

switch(action.type) {

default:

return state;

}

}

(2)home/index

方便管理与导出

import reducer from './reducer';

export {reducer};

(3)分析是否可以使用

我们的Provider包裹了我们的home,而home又包裹了Topic,完全可以从中获取数据

import React, { Component} from 'react';

import { BrowserRouter, Route} from 'react-router-dom';

import Header from './common/header';

import Home from './pages/home';

import Detail from './pages/detail'

import store from './store';

import { Provider } from 'react-redux';

class App extends Component {

render() {

return (

);

}

}

export default App;

(4)与src/reducr建立联系

import { reducer as headerReducer } from '../common/header/store';

import {reducer as homeReducer} from '../pages/home/store';

//import { combineReducers } from 'redux';

import { combineReducers } from 'redux-immutable';

const reducer = combineReducers({

header: headerReducer,

home: homeReducer

});

export default reducer;

(5)使用数据

import React, {Component} from 'react';

import {connect} from 'react-redux';

import {

TopicWrapper,

TopicItem

} from '../style';

class Topic extends Component {

render() {

const {list} = this.props;

return (

{

list.map((item) => (

//immutable获取要使用get

className='topic-pic'

src={ item.get('imgUrl')} alt='tu'

/>

{item.get('title')}

))

}

)

}

}

const mapState = (state) => ({

list: state.get('home').get('topicList')

})

export default connect(mapState, null)(Topic);

4 首页文章列表制作

4.1 样式布局

布局的方式基本上就和专题布局的方式差不多,先进行样式的布局,因为内容分为两类:

1.有图片

2.无图片

import React, { Component } from 'react';

import { connect } from 'react-redux';

import {

ListItem,

ListInfo

} from '../style'

class Lsit extends Component {

render() {

const {list} = this.props;

return (

react.js 简书项目实战-main首页开发  第2张

撒贝宁说:我对自己的婚姻非常失望

在参加一档节目中,谈到婚姻,撒贝宁公开说道:“我觉得自己的婚姻非常的无望,也没有继续维持下去的必要。”惹得现场观众大吃一惊。 事实上当时马东故意...

我摆地摊,最惨痛的教训

曾经,我摆过一次摊,在龙眼丰收的7月里,进了30斤新鲜龙眼,进货价3元一斤,打算以5元单价出售。 找了个人流量大的道路旁,铺开一张垫子,挑选一些...

)

}

}

export default Lsit;

style.js

export const TopicWrapper = styled.div`

overflow: hidden;

padding: 20px 0 10px 0;

margin-left: -18px;

border-bottom: 1px solid #dcdcdc; //专题下加一个底线

`

export const ListItem = styled.div`

overflow: hidden;

padding: 15px 0;

border-bottom: 1px solid #dcdcdc;

.pic {

position: relative;

top: 30px;

float: right;

width: 150px;

height: 100px;

border: 1px solid #f0f0f0;

border-radius: 4px;

}

`

export const ListInfo = styled.div`

width: 460px;

float: left;

.title {

line-height: 18px;

font-size: 18px;

font-weight: bold;

color: #333;

margin-block-start: 10px;

margin-block-end: 10px;

}

.desc {

font-size: 13px;

line-height: 24px;

color: #999;

}

.noimgdesc {

width: 640px;

font-size: 13px;

line-height: 24px;

color: #999;

}

`

结果如图所示:

4.2 数据管理

我们在reducer中增加我们需要的数据

import { fromJS } from 'immutable';

//将其变为immutable

const defaultState = fromJS({

topicList: [{

id: 1,

title: '社会热点',

imgUrl: '//upload.jianshu.io/collections/images/261938/man-hands-reading-boy-large.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/64/h/64'

},{

id:2,

title: '手绘',

imgUrl: '//upload.jianshu.io/collections/images/21/20120316041115481.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/64/h/64'

}],

articleLists: [{

id: 1,

title: '撒贝宁说:我对自己的婚姻非常失望',

desc: '在参加一档节目中,谈到婚姻,撒贝宁公开说道:“我觉得自己的婚姻非常的无望,也没有继续维持下去的必要。”惹得现场观众大吃一惊。 事实上当时马东故意...',

imgUrl: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1598593565605&di=7e03a7f64bab11b3da0a67f9a6b5ff41&imgtype=0&src=http%3A%2F%2Fn.sinaimg.cn%2Fsinacn%2Fw480h339%2F20180226%2F0d93-fyrwsqi3956378.jpg',

imgAlt: '撒贝宁'

},{

id: 2,

title: '我摆地摊,最惨痛的教训',

desc: '曾经,我摆过一次摊,在龙眼丰收的7月里,进了30斤新鲜龙眼,进货价3元一斤,打算以5元单价出售。 找了个人流量大的道路旁,铺开一张垫子,挑选一些...',

imgUrl: null

},{

id: 3,

title: '撒贝宁说:我对自己的婚姻非常失望',

desc: '在参加一档节目中,谈到婚姻,撒贝宁公开说道:“我觉得自己的婚姻非常的无望,也没有继续维持下去的必要。”惹得现场观众大吃一惊。 事实上当时马东故意...',

imgUrl: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1598593565605&di=7e03a7f64bab11b3da0a67f9a6b5ff41&imgtype=0&src=http%3A%2F%2Fn.sinaimg.cn%2Fsinacn%2Fw480h339%2F20180226%2F0d93-fyrwsqi3956378.jpg',

imgAlt: '撒贝宁'

},{

id: 4,

title: '我摆地摊,最惨痛的教训',

desc: '曾经,我摆过一次摊,在龙眼丰收的7月里,进了30斤新鲜龙眼,进货价3元一斤,打算以5元单价出售。 找了个人流量大的道路旁,铺开一张垫子,挑选一些...',

imgUrl: null

}]

});

export default (state = defaultState, action) => {

switch(action.type) {

default:

return state;

}

}

在list中显示,注意不同的类型返回不同的样式。根据是否有imgUrl进行判断。

import React, { Component } from 'react';

import { connect } from 'react-redux';

import {

ListItem,

ListInfo

} from '../style'

class Lsit extends Component {

render() {

const {list} = this.props;

return (

{

list.map((item) => {

if(item.get('imgUrl')){

return (

react.js 简书项目实战-main首页开发  第3张

{item.get('title')}

{item.get('desc')}

)

}else{

return (

{item.get('title')}

{item.get('desc')}

)

}

})

}

)

}

}

const mapState = (state) => ({

list: state.getIn(['home', 'articleLists'])

})

export default connect(mapState, null)(Lsit);

4.3 其它更改

这里的搜索的背景变为了透明,我们返回header/style中找到SearchInfo,将背景变为白色 background: #fff;

export const SearchInfo = styled.div`

position: absolute;

left: 0;

top: 56px;

width:240px;

padding: 0 20px;

box-shadow: 0 0 8px rgba(0, 0, 0, .2);

background: #fff;

`

5 首页推荐部分代码编写

5.1 样式布局

这个布局相对比较简单

Recommend.js

注意 组件必须大写!!!!!!

import React, {Component} from 'react';

import {

RcommendItem

} from '../style'

class Recommend extends Component {

render() {

return (

react.js 简书项目实战-main首页开发  第4张

react.js 简书项目实战-main首页开发  第4张

)

}

}

export default Recommend;

style.js

export const RcommendItem = styled.div`

width: 280px;

height: 225px;

padding: 6px 0;

.pic {

width: 280px;

height: 50px;

}

`

//我们把右边调低了 20px 为了使得页面更美观

export const HomeRight = styled.div`

position: relative;

top: 20px;

width: 280px;

float: right;

`

结果:

5.2 数据管理

reducer中存储的数据

recommendPic: [{

id: '1',

imgUrl:"https://cdn2.jianshu.io/assets/web/banner-s-club-aa8bdf19f8cf729a759da42e4a96f366.png"

},{

id: '2',

imgUrl: "https://cdn2.jianshu.io/assets/web/banner-s-7-1a0222c91694a1f38e610be4bf9669be.png"

},{

id: '3',

imgUrl:"https://cdn2.jianshu.io/assets/web/banner-s-5-4ba25cf5041931a0ed2062828b4064cb.png"

},{

id: '4',

imgUrl: "https://cdn2.jianshu.io/assets/web/banner-s-6-c4d6335bfd688f2ca1115b42b04c28a7.png"

}]

数据的加载与处理

import React, {Component} from 'react';

import { connect } from 'react-redux';

import {

RcommendItem

} from '../style'

class Recommend extends Component {

render() {

const {list} = this.props;

return (

{

list.map((item) => {

return (

react.js 简书项目实战-main首页开发  第6张

)

})

}

)

}

}

const mapState = (state) => ({

list: state.getIn(['home', 'recommendPic'])

})

export default connect(mapState, null)(Recommend);

当前页面:

补充

视频中的语法,传递到样式中的值的使用

6 作者部分代码编写

注:我们实现样式不实现换一换的动作,实现如下图的样式

6.1 样式布局

writer.js

import React, {Component} from 'react';

import {

WriterHeader,

WriterSwitch,

WriterItem,

WriterName,

WriterDesc,

WriterFlower,

WriterInfo,

Allwriters

} from '../style'

class Writer extends Component {

render() {

return (

推荐作者

换一批

react.js 简书项目实战-main首页开发  第7张

+关注

Rose的肉丝儿

写了151.5k字 · 13k喜欢

react.js 简书项目实战-main首页开发  第7张

+关注

Rose的肉丝儿

写了151.5k字 · 13k喜欢

查看全部

)

}

}

export default Writer;

style.js

export const WriterItem = styled.div`

width: 285px;

overflow: hidden;

.head {

width: 50px;

height: 50px;

border: 1px solid #ddd;

border-radius: 50%;

float: left;

}

`

export const WriterHeader = styled.div`

font-size: 14px;

color: #969696;

margin-bottom: 18px;

`

export const WriterSwitch = styled.div`

float: right;

font-size: 14px;

color: #969696;

.spin {

display: block;

position: relative;

top:5px;

float: left;

width: 12px;

height: 12px;

color: red;

margin-right: 2px;

}

`

export const WriterInfo = styled.div`

overflow: hidden;

width: 230px;

margin-top: 4px;

margin-left: 60px;

margin-bottom: 20px;

`

export const WriterName = styled.div`

font-size: 14px;

color: #333;

`

export const WriterFlower = styled.span`

float: right;

margin-right: 10px;

font-size: 13px;

color: #42c02e;

`

export const WriterDesc = styled.div`

margin-top: 8px;

font-size: 12px;

color: #969696;

`

export const Allwriters = styled.div`

position: absolute;

width: 258px;

padding: 7px 7px 7px 12px;

left: 0;

font-size: 13px;

color: #787878;

background-color: #f7f7f7;

border: 1px solid #dcdcdc;

border-radius: 4px;

text-align: center;

`

实现效果:

6.2 数据编写

reducer中的数据

WirterList: [

{id:"14715425",nickname:"简书钻首席小管家",avatar_source:"https://upload.jianshu.io/users/upload_avatars/14715425/e0668349-8c75-43db-8a9d-c388e5f00d0d.jpg",total_likes_count:"101307",total_wordage:"462675"},

{id:"6652326",nickname:"没文化的野狐狸",avatar_source:"https://upload.jianshu.io/users/upload_avatars/6652326/498e86b9-7067-4e96-b5f2-6438089e2da1.jpg",total_likes_count:"6174",total_wordage:"319160"},

{id:"7290998",nickname:"念远怀人",avatar_source:"https://upload.jianshu.io/users/upload_avatars/7290998/f64f5ef0-def0-4b26-beb3-b9d88f060ba0.jpg",total_likes_count:"14246",total_wordage:"685673"},

{id:"7663825",nickname:"名贵的考拉熊",avatar_source:"https://upload.jianshu.io/users/upload_avatars/7663825/7c28763e-002b-4e89-8dea-5b8da210ef2c.jpg",total_likes_count:"19585",total_wordage:"267784"},

{id:"278",nickname:"邓哲",avatar_source:"https://upload.jianshu.io/users/upload_avatars/278/0778727c-c557-4ffb-929c-6ee182a58145.png",total_likes_count:"1494",total_wordage:"434008"}

]

writer.js

注意:显示的时候将数字单位转换为k,并取一位小数

import React, {Component} from 'react';

import { connect } from 'react-redux';

import {

WriterHeader,

WriterSwitch,

WriterItem,

WriterName,

WriterDesc,

WriterFlower,

WriterInfo,

Allwriters

} from '../style'

class Writer extends Component {

render() {

const {list} = this.props;

const switchNum = (num) => {

if(num > 1000){

num = parseFloat(num / 1000);

num = num.toFixed(1);

const final = num + "k";

return final;

}else{

return num;

}

}

return (

推荐作者

换一批

{

list.map((item) => {

return (

react.js 简书项目实战-main首页开发  第9张

+关注

{item.get('nickname')}

写了{switchNum(item.get('total_wordage'))}字 · {switchNum(item.get('total_likes_count'))}喜欢

)

})

}

查看全部

)

}

}

//注意方括号

const mapState = (state) => ({

list: state.getIn(['home', 'WirterList'])

})

export default connect(mapState,null)(Writer);

最终代码:

项目地址:https://github.com/Hokwok/jianshu

好文阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: