用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中运行并行任务技巧
Feb 26 Python
python通过邮件服务器端口发送邮件的方法
Apr 30 Python
Python如何读取MySQL数据库表数据
Mar 11 Python
Python numpy 常用函数总结
Dec 07 Python
PYTHON基础-时间日期处理小结
May 05 Python
django解决跨域请求的问题详解
Jan 20 Python
python3.7实现云之讯、聚合短信平台的短信发送功能
Sep 26 Python
python实现计算器功能
Oct 31 Python
Python imageio读取视频并进行编解码详解
Dec 10 Python
在keras 中获取张量 tensor 的维度大小实例
Jun 10 Python
python利用google翻译方法实例(翻译字幕文件)
Sep 21 Python
Pygame Time时间控制的具体使用详解
Nov 17 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
phpadmin如何导入导出大数据文件及php.ini参数修改
2013/02/18 PHP
php-fpm配置详解
2014/02/12 PHP
Yii2中cookie用法示例分析
2016/07/18 PHP
PHP实现通过CURL上传文件功能示例
2018/05/30 PHP
MSN消息提示类
2006/09/05 Javascript
HTML DOM的nodeType值介绍
2011/03/31 Javascript
jquery mobile页面跳转后样式丢失js失效的解决方法
2014/09/06 Javascript
jQuery $命名冲突解决方案汇总
2014/11/13 Javascript
node.js中的querystring.stringify方法使用说明
2014/12/10 Javascript
JQuery中的事件及动画用法实例
2015/01/26 Javascript
jquery实现手风琴效果
2015/11/20 Javascript
JavaScript仿商城实现图片广告轮播实例代码
2016/02/06 Javascript
JavaScript操作表单实例讲解(上)
2016/06/20 Javascript
浅析JavaScript中break、continue和return的区别
2016/11/30 Javascript
基于Vue实现拖拽效果
2018/04/27 Javascript
JavaScript原型式继承实现方法
2019/11/06 Javascript
python之验证码生成(gvcode与captcha)
2019/01/02 Python
pyqt5中QThread在使用时出现重复emit的实例
2019/06/21 Python
通过实例解析Python return运行原理
2020/03/04 Python
Python和Bash结合在一起的方法
2020/11/13 Python
python可视化 matplotlib画图使用colorbar工具自定义颜色
2020/12/07 Python
pytest fixtures装饰器的使用和如何控制用例的执行顺序
2021/01/28 Python
css3动画事件—webkitAnimationEnd与计时器time事件
2013/01/31 HTML / CSS
HTML5的标签的代码的简单介绍 HTML5标签的简介
2012/05/28 HTML / CSS
HTML5+CSS3:3D展示商品信息示例
2017/01/03 HTML / CSS
英国体育器材进口商店:UK Sport Imports
2017/03/14 全球购物
师范生实习的个人自我鉴定
2013/10/20 职场文书
上级检查欢迎词
2014/01/18 职场文书
给面试官的感谢信
2014/02/01 职场文书
品质管理部岗位职责范文
2014/03/01 职场文书
进口业务员岗位职责
2014/04/06 职场文书
优秀护士先进事迹
2014/05/08 职场文书
检察机关个人对照检查材料
2014/09/15 职场文书
Elasticsearch 数据类型及管理
2022/04/19 Python
Java对文件的读写操作方法
2022/04/29 Java/Android
Spring Boot 实现 WebSocket
2022/04/30 Java/Android