完成详情页渲染,用到了react-markdown来渲染
先看效果:

1 在components下新建Detail.js

import React , { Component }from 'react';
import { Card, Avatar, Spin, Icon,Comment, Tooltip, List} from 'antd';
import PropTypes from 'prop-types';
import { connect } from 'dva';
import  ReactMarkdown from 'react-markdown';
import './my.css';class Detail extends Component{render() {const { Meta } = Card;return (<Spin spinning={this.props.loading.global}size='large'tip="数据正在加载中">{typeof(this.props.data.author)=='object' ? (<Card><Cardtype="inner"title={<div><Avatar src={this.props.data.author.avatar_url} />&nbsp;&nbsp;&nbsp;<span style={{fontSize :26}}>{this.props.data.title}</span></div>}extra={<div>发布于{this.props.data.create_at} *作者{this.props.data.author.loginname}*  {this.props.data.visit_count}次浏览  *来自 分享</div>}><ReactMarkdown source={this.props.data.content} /></Card><Cardtype="inner"title={this.props.data.reply_count+'个回复'}><ListclassName="comment-list"itemLayout="horizontal"dataSource={this.props.data.replies}renderItem={item => (<Commentauthor={item.author.loginname}avatar={item.author.avatar_url}content={<ReactMarkdown source={item.content} />}datetime={item.create_at}/>)}/></Card></Card>) : ''}</Spin>)}componentWillMount () {const { par } = this.propsthis.props.dispatch({ type: 'detail/find', payload: { id:par} })}
}Detail.propTypes = {id: PropTypes.string.isRequired,
};function mapStateToProps(state) {const {id,data} = state.detail;return {id,data,loading:state.loading};
}// export default ListData;
export default connect(mapStateToProps)(Detail);

用到了antd中的一些组件,可以自己去官网参考下怎么用。 my.css里面定义了一些样式,主要解决markdown渲染后里面的图片太宽,重新设置宽度。


a{text-decoration:none;color:#333;
}img{max-width: 1300px;
}

2 在models下创建对应的model detail.js

import * as listService from '../services/list';
export default {namespace: 'detail',state:{id:'',data:{}},effects: {*find({ payload: { id } }, { call, put }) {const result = yield call(listService.find, { id })yield put({type: 'updateData',payload: {result,id}})}},reducers: {'updateData'(state, { payload: data }) {let r = data.result.dataconst {id} = datareturn {...state,id,data:r}}},subscriptions : {setup({ dispatch, history }) {}
},
};

3 在service中添加获取详情的api list.js

import request from '../utils/request';export function query({ page,pageSize,type }) {return request(`/api/v1/topics?page=${page}&limit=${pageSize}&tab=${type}`);
}export function find({ id }) {return request(`/v1/topic/${id}?mdrender=false`);
}

mdrender参数设置为false来获取markdown数据,truehtml数据

4 创建详情页routes/DetailPage.js

import React from 'react';
import { connect } from 'dva';
import Header from '../components/Header';
import Detail from '../components/Detail';function DetailPage(props) {const {params} = props.matchreturn (<div><Header keys={['index']}/><div style={{paddingTop:20,paddingLeft:100,paddingRight:100,paddingBottom:50}}><Detail par={params.id}/></div></div>);
}DetailPage.propTypes = {
};export default connect()(DetailPage);

使用了自己定义的HeaderDetail组件。在router.js中邦定路由到页面:

import React from 'react';
import { Router, Route, Switch } from 'dva/router';
import IndexPage from './routes/IndexPage';
import DetailPage from './routes/DetailPage';function RouterConfig({ history }) {return (<Router history={history}><Switch><Route path="/" exact component={IndexPage} /><Route path="/detail/:id" exact component={DetailPage} /></Switch></Router>);
}export default RouterConfig;

使用了参数路由,在DetailPage.js中,从props.match.params中就可以取到id值传给Detail组件

5 别忘了在index.js中注册model以及插件

import dva from 'dva';
import './index.css';
import createLoading from 'dva-loading';// 1. Initialize
const app = dva();// 2. Pluginsapp.use(createLoading());// 3. Model
app.model(require('./models/listdata').default);
app.model(require('./models/detail').default);// 4. Router
app.router(require('./router').default);// 5. Start
app.start('#root');

前面两节课忘说dva-loading了,需要在这里使用,才能在组件中获取loading属性

6 在ListData组件中加入路由跳转详情页

import {Link} from 'dva/router';
<Link to={'/detail/'+item.id}>{item.title}</Link>

使用了Link来做跳转,顺带把我们的Header组件的跳转也给改了

 <Menu.Item key="index"><Link to="/"><Icon type="appstore" />首页</Link></Menu.Item><Menu.Item key="into"><Link to="/into"><Icon type="appstore" />新手入门</Link></Menu.Item><Menu.Item key="api"><Link to="/api"><Icon type="appstore" />API</Link></Menu.Item><Menu.Item key="about"><Link to="/about"><Icon type="appstore" />关于</Link></Menu.Item><Menu.Item key="reg"><Link to="/reg"><Icon type="appstore" />注册</Link></Menu.Item><Menu.Item key="login"><Link to="/login"><Icon type="appstore" />登陆</Link></Menu.Item>

大功告成看看效果

欢迎关注我的公众号mike啥都想搞,学习更多内容。

React实战入门课程:dva开发一个cnode网站(3)相关推荐

  1. flask学习:开发一个微电影网站一:项目介绍

    最近在学习flask,完成了入门学习,现在想找一个项目进行实战学习,看看系统的开发是怎么样的,然后看到了慕课网上有一个视频,使用flask开发一个微电影网站,因此决定花时间学习一下. 一:首先介绍一下 ...

  2. 从零开始开发一个大型网站

    从零开始开发一个大型网站 更新:前端代码已全部由TypeScript进行重写 这是本人第一个从零开始开发一个大型网站(前后端+部署代码),是一个内容分享社区,详细信息见github.目前还是开发中后期 ...

  3. 如何使用MyEclipse开发一个JavaWeb网站

    如何使用MyEclipse开发一个JavaWeb网站 本文所述的内容仅用于参考或学习,主要针对毕业设计等网站设计,请勿实际用于生产开发用途,否则后果自负: 如何使用MyEclipse开发一个JavaW ...

  4. 【教你如何开发一个OnlineJudge网站】第一章 如何实现OnlineJudge判题

    [教你如何开发一个OnlineJudge网站]系列文章目录 第一章 如何实现OnlineJudge判题 第二章 实现OnlineJudge的后端 第三章 实现OnlineJudge的前端 文章目录 [ ...

  5. Python Web实战:Flask + Vue 开发一个漂亮的词云网站

    作者:snowspace@掘金 前言 大家好,我是菜鸟哥!Python里面两大最牛的Web框架,一个是Django,一个是Flask .今天就分享一个用Flask做的词云生成网站,非常有意思的小web ...

  6. 实战|轻松用 Python 开发一个简单有趣的聊天小程序

    前言 Internet 协议集支持一个无连接的传输协议,该协议称为用户数据报协议(UDP,User Datagram Protocol). UDP 为应用程序提供了一种无需建立连接就可以发送封装的 I ...

  7. Flask 项目实战|从零开发“StackOverflow”问答网站

    StackOverflow 是全球最大的 IT 技术问答网站之一,在程序员界无人不知无人不晓,堪称"面向搜索引擎编程"神器.下图就是 StackOverflow 网站首页图: 是不 ...

  8. 模块化开发一个电子商务网站

    通过查看网上的教学视频,跟着做下来这样一个电子商务网站整站开发的项目.整个页面写下来还是很耗时的,页面的细节太多,得仔仔细细核对原设计图,1px也要在那里死抠,不能放过,不然怕影响整体布局.关于浏览器 ...

  9. 基于Appian低代码平台开发一个SpaceX网站

    文章目录 Appian 背景摘要 Appian Designer SpaceX网站开发 新建Application 配置应用权限 创建Record Type Appian 背景摘要 国内几乎没有App ...

  10. 实战|使用 Python 开发一个在线聊天室

    「来源: |Python爬虫与数据挖掘 ID:crawler_python」 回复"书籍"即可获赠Python从入门到进阶共10本电子书 今 日 鸡 汤 云想衣裳花想容,春风拂槛露 ...

最新文章

  1. Anaconda+用conda创建python虚拟环境
  2. swift 用协议实现代理传值功能
  3. python的protected和private
  4. 【JavaScript】理解与使用Javascript中的回调函数
  5. 安卓手机运行ios教程_英雄联盟手游傻瓜安装教程,IOS/安卓双端可用!
  6. dos, echo写文件不追加回车的方法
  7. 二分查找 —— 有序数组不小于(不大于)某数的第一个(最后一个)元素
  8. 【Thinking In Java】笔记之一 一切都是对象
  9. 旋转矩阵之到底顺时针还是逆时针
  10. 蓝牙音乐SRC侧的安卓实现
  11. w ndows系统开机时黑屏,Win10系统更新后,开机黑屏怎么办?
  12. 记录12款MacBook Pro MC946,A1398拆主板换新喇叭的过程
  13. Python 实现 GIF 动态图片分解 , 多帧动态图分解成多张静态图片
  14. 还弄不懂相对路径和绝对路径,这篇文章带你简单剖析
  15. 玩转数据可视化之R语言ggplot2:(八)ggplot2绘制空间地理数据图
  16. 无锡做大做强“中国芯” 华虹功不可没
  17. python-scrapy-MongoDB 爬取链家二手房
  18. [ZT]JavaScript+div实现模态对话框[修正版]
  19. 机器学习实战2.2. k-近邻算法例子-优化约会网站的配对效果
  20. 【吴恩达深度学习编程作业】4.4特殊应用——人脸识别和神经风格转换(问题未解决)

热门文章

  1. python股票交易系统实现_python实现股票自动交易,自动量化交易软件
  2. 用python对excel进行图表操作
  3. 操作系统MOOC课后习题答案
  4. java捕鱼达人代码java捕鱼游戏代码
  5. uniapp小程序优化和减小代码体积的方式
  6. vscode中微信小程序的代码智能提示
  7. live2d_原画人插画教程,想知道live2d虚拟主播是怎么制作出来的吗?
  8. 23种Python设计模式之工厂方法模式详解
  9. Pycharm安装Markdown插件
  10. java基于ssm+vue的办公耗材采购管理系统