用ReactJS和Python的Flask框架编写留言板的代码示例


Posted in Python onDecember 19, 2015

近期要在生产环境上使用react,所以,自己学习了一下,写了一个简单的留言板小程序。完整的代码可以到这里下载:message-board

Use

前端使用React,然后还有Bootstrap和jQuery,React负责前端展现,jQuery主要是向服务器发送ajax请求。
后端使用Flask和MongoDB,为前端提供数据。这里主要关注前端,对于后端不做过多说明。
使用webpack,对js文件进行打包。

About React

React是facebook开发一个用于前段交互的Javascript库。
刚刚开始使用,有这么几个特点:
1. 组件化开发。React提倡无状态的组件,便于重用。
2. VirtualDOM。React的性能比较高,得益于虚拟DOM。它不会每次都去直接操作DOM,因为操作DOM的代价是很大的,所以,它在内存中维护了虚拟DOM,通过计算虚拟DOM和浏览器上的DOM的变更进行操作。
3. 专注于View。React不是MVC框架,它只是一个专注于View的库,所以,它也可以和很多其他框架或者库一起使用。
4. 提供完成的生命周期。

Message Board

这个留言板小应用,主要有这样几个功能:
1.添加留言,一个表单:用户名和内容
2.列表展示,显示所有留言
3.简单的分页

Code

使用React,就要对应用进行组件的切分,尽量保持组件的无状态。

App

从宏观上组织整个应用,切分三个大组件:
1. MessageForm,添加留言表单。
2. MessageList,留言列表
3. Pager,留言的分页控制
当然,组件还可以继续划分。
子组件的数据都会回调到MessageBoard中,在这里统一控制。
MessageBoard.js

var React = require("react");
var MessageList = require("./MessageList");
var MessageForm = require("./MessageForm");
var Pager = require("./Pager");

var MessageBoard = React.createClass({
 getInitialState : function(){
  return {
   messages: [],
   page:0,
   pages:0
  }
 },
 submitMessage : function (author, content) {
  $.ajax({
   type:'post',
   url:'/message',
   data:{author:author,content:content}
  }).done(function (data) {
   console.log(data);
   this.listMessage(1);
  }.bind(this));
 },
 listMessage : function(page){
  console.log("listMessages page:"+page)
  $.ajax({
   type:'get',
   url:'/messages',
   data:{page:page}
  }).done(function (resp) {
   if(resp.status == "success"){
    var pager = resp.pager;
    console.log(pager);
    this.setState({
     messages:pager.messages,
     page:pager.page,
     pages:pager.pages
    });
   }
  }.bind(this));
 },
 componentDidMount : function(){
  this.listMessage(1);
 },
 render : function(){
  var pager_props = {
   page : this.state.page,
   pages : this.state.pages,
   listMessage : this.listMessage
  };
  return(


<div>
    <MessageForm submitMessage={this.submitMessage}/>
    <MessageList messages = {this.state.messages}/>
    <Pager {...pager_props}/>
   </div>


  )
 }
});

module.exports = MessageBoard;

MessageForm

一个简单的表单,保存留言。用户提交后,数据会传给父组件。
MessageForm.js

var React = require("react");

var MessageForm = React.createClass({
 handleSubmit : function (e) {
  e.preventDefault();
  var author = this.refs.author.getDOMNode().value.trim();
  var content = this.refs.content.getDOMNode().value.trim();

  this.props.submitMessage(author,content);

  this.refs.author.getDOMNode().value = "";
  this.refs.content.getDOMNode().value = ""
 },
 render : function(){
  return(
    <div className="well">
     <h4>Leave a Message:</h4>
     <div role="form">
      <div className="form-group">
       <input ref="author" className="form-control" placeholder="Name"/>
       <textarea ref="content" className="form-control" rows="3" placeholder="Leave your message here"></textarea>
      </div>
      <a className="btn btn-primary" onClick={this.handleSubmit}>Submit</a>
     </div>
    </div>
  )
 }
});
module.exports = MessageForm;

MessageList

留言的列表展示,在写列表之前,把每条留言写成一个组件
Message.js

var React = require("react");

var Message = React.createClass({
 render : function(){
  var msg = this.props.message;
  return(


<div>
    <h3>{msg.author}  
     <small>{msg.time.toLocaleString()}</small>
    </h3>
    <p>{msg.content}</p>
   </div>


  )
 }
});

module.exports = Message;

然后,再写列表.
数据从父组件通过props传递进来
MessageList.js

var React = require("react");
var Message = require("./Message");

var MessageList = React.createClass({
 render : function () {
  var messages = this.props.messages.map(function(item){
   return <Message message={item}/>
  });
  console.log(messages);
  return(
   <div>
    {messages}
   </div>
  )
 }
});

module.exports = MessageList;

Pager

这是一个简单的分页,会显示当前页和总页数,还有上一页和下一页功能。
Pager.js

var React = require("react/addons");

var Pager = React.createClass({
 getDefaultProps : function(){
  return{
   page:0,
   pages:0
  }
 },
 clickHandler: function(e){
  e.preventDefault();
  console.log(e.target.dataset.page);
  console.log(e.target.dataset.page.value);
  this.props.listMessage(e.target.dataset.page);

 },
 render : function(){
  var cx = React.addons.classSet;
  var preClass = cx({
   'previous':true,
   'disabled':this.props.page == 1
  });
  var nextClass = cx({
   'next':true,
   'disabled':this.props.page == this.props.pages
  });

  return(
   <ul className="pager">
    <li className={preClass} onClick={this.clickHandler}>
     <a href="#" data-page={this.props.page-1}>←Prev</a>
    </li>
    <li>
     <span>{this.props.page}/{this.props.pages}</span>
    </li>
    <li className={nextClass} onClick={this.clickHandler}>
     <a href="#" data-page={this.props.page+1}>Next→</a>
    </li>
   </ul>
  )
 }
});

module.exports = Pager;

Summary

一个简单的小程序只能简单的感受一下React,这个库的思路和当前流行的库和框架相比,还是比较新颖的,值得学习~

Python 相关文章推荐
python ElementTree 基本读操作示例
Apr 09 Python
高质量Python代码编写的5个优化技巧
Nov 16 Python
python按行读取文件,去掉每行的换行符\n的实例
Apr 19 Python
python元组的概念知识点
Nov 19 Python
python 多维高斯分布数据生成方式
Dec 09 Python
Python networkx包的实现
Feb 14 Python
Pyecharts 动态地图 geo()和map()的安装与用法详解
Mar 25 Python
python MultipartEncoder传输zip文件实例
Apr 07 Python
解决jupyter notebook import error但是命令提示符import正常的问题
Apr 15 Python
为什么python比较流行
Jun 19 Python
pytorch锁死在dataloader(训练时卡死)
May 28 Python
python缺失值填充方法示例代码
Dec 24 Python
使用Python编写简单的端口扫描器的实例分享
Dec 18 #Python
十个Python程序员易犯的错误
Dec 15 #Python
Python学习笔记整理3之输入输出、python eval函数
Dec 14 #Python
Python中内置数据类型list,tuple,dict,set的区别和用法
Dec 14 #Python
分享Python字符串关键点
Dec 13 #Python
Python实时获取cmd的输出
Dec 13 #Python
一篇文章入门Python生态系统(Python新手入门指导)
Dec 11 #Python
You might like
php 什么是PEAR?(第二篇)
2009/03/19 PHP
PHP实现基于图的深度优先遍历输出1,2,3...n的全排列功能
2017/11/10 PHP
thinkPHP3.2使用RBAC实现权限管理的实现
2019/08/27 PHP
php使用自带dom扩展进行元素匹配的原理解析
2020/05/29 PHP
JavaScript高级程序设计 事件学习笔记
2011/09/10 Javascript
JS函数this的用法实例分析
2015/02/05 Javascript
jQuery表单域属性过滤器用法分析
2015/02/10 Javascript
javascript使用shift+click实现选择和反选checkbox的方法
2015/05/04 Javascript
JavaScript学习小结之被嫌弃的eval函数和with语句实例详解
2016/08/01 Javascript
JS获取字符串实际长度(包含汉字)的简单方法
2016/08/11 Javascript
Vuejs第八篇之Vuejs组件的定义实例解析
2016/09/05 Javascript
微信小程序加载更多 点击查看更多
2016/11/29 Javascript
bootstrap实现图片自动轮播
2016/12/21 Javascript
Vue实现双向数据绑定
2017/05/03 Javascript
webpack 样式加载的实现原理
2018/06/12 Javascript
小程序红包雨的实现示例
2019/02/19 Javascript
[01:01]2020完美高校联赛(秋)西安落幕
2021/03/11 DOTA
Python 给某个文件名添加时间戳的方法
2018/10/16 Python
Python寻找两个有序数组的中位数实例详解
2018/12/05 Python
python 实现分页显示从es中获取的数据方法
2018/12/26 Python
python中通过selenium简单操作及元素定位知识点总结
2019/09/10 Python
python SVD压缩图像的实现代码
2019/11/05 Python
使用 prometheus python 库编写自定义指标的方法(完整代码)
2020/06/29 Python
Python collections模块的使用方法
2020/10/09 Python
css3 box-shadow阴影(外阴影与外发光)图示讲解
2017/08/11 HTML / CSS
HTML5如何为形状图上颜色怎么绘制具有颜色和透明度的矩形
2014/06/23 HTML / CSS
白色公司:The White Company
2017/10/11 全球购物
美国二手复古奢侈品包包购物网站:LXRandCo
2019/06/18 全球购物
《我为你骄傲》教学反思
2014/02/20 职场文书
工程管理英文求职信
2014/03/18 职场文书
主题教育活动总结
2014/05/05 职场文书
大学生安全教育主题班会
2015/08/12 职场文书
导游词之扬州大明寺
2019/10/09 职场文书
Pytorch反向传播中的细节-计算梯度时的默认累加操作
2021/06/05 Python
纯CSS3实现div按照顺序出入效果
2021/07/15 HTML / CSS
zabbix配置nginx监控的实现
2022/05/25 Servers