用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利用hook技术破解https的实例代码
Mar 25 Python
python关闭windows进程的方法
Apr 18 Python
深入理解Python中range和xrange的区别
Nov 26 Python
urllib和BeautifulSoup爬取维基百科的词条简单实例
Jan 17 Python
python opencv检测目标颜色的实例讲解
Apr 02 Python
python读取csv文件并把文件放入一个list中的实例讲解
Apr 27 Python
Python使用matplotlib绘制随机漫步图
Aug 27 Python
Python3.6简单的操作Mysql数据库的三个实例
Oct 17 Python
python遍历文件目录、批量处理同类文件
Aug 31 Python
python 字典的打印实现
Sep 26 Python
解决Keras 中加入lambda层无法正常载入模型问题
Jun 16 Python
手把手教你配置JupyterLab 环境的实现
Feb 02 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
改造一台复古桌面收音机
2021/03/02 无线电
封装一个PDO数据库操作类代码
2009/09/09 PHP
php简单开启gzip压缩方法(zlib.output_compression)
2013/04/13 PHP
Zend Framework教程之请求对象的封装Zend_Controller_Request实例详解
2016/03/07 PHP
php 二维数组时间排序实现代码
2016/11/19 PHP
javascript的键盘控制事件说明
2008/04/15 Javascript
js parsefloat parseint 转换函数
2010/01/21 Javascript
加速IE的Javascript document输出的方法
2010/12/02 Javascript
jquery拖拽效果完整实例(附demo源码下载)
2016/01/14 Javascript
javascript拖拽效果延伸学习
2016/04/04 Javascript
浅析JavaScript中浏览器的兼容问题
2016/04/19 Javascript
小白谈谈对JS原型链的理解
2016/05/03 Javascript
react性能优化达到最大化的方法 immutable.js使用的必要性
2017/03/09 Javascript
原生JS实现自定义滚动条效果
2020/10/27 Javascript
vue使用vue-cli快速创建工程
2017/07/28 Javascript
Vuex 进阶之模块化组织详解
2018/01/12 Javascript
从零开始用electron手撸一个截屏工具的示例代码
2018/10/10 Javascript
vue项目中mock.js的使用及基本用法
2019/05/22 Javascript
javascript实现简单页面倒计时
2021/03/02 Javascript
Python中用Spark模块的使用教程
2015/04/13 Python
Python切片操作深入详解
2018/07/27 Python
django项目搭建与Session使用详解
2018/10/10 Python
python for循环输入一个矩阵的实例
2018/11/14 Python
tensorflow通过模型文件,使用tensorboard查看其模型图Graph方式
2020/01/23 Python
PyCharm刷新项目(文件)目录的实现
2020/02/14 Python
Python greenlet和gevent使用代码示例解析
2020/04/01 Python
Python3安装模块报错Microsoft Visual C++ 14.0 is required的解决方法
2020/07/28 Python
如何使用PyCharm引入需要使用的包的方法
2020/09/22 Python
python-地图可视化组件folium的操作
2020/12/14 Python
美国一家著名的手表在线折扣网站:Discount Watch Store
2020/02/24 全球购物
鲜果饮品店创业计划书
2014/01/21 职场文书
军事博物馆观后感
2015/06/05 职场文书
初中军训感想
2015/08/07 职场文书
2015年小学体育教师工作总结
2015/10/23 职场文书
2016大学军训通讯稿
2015/11/25 职场文书
对Keras自带Loss Function的深入研究
2021/05/25 Python