用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实现bitmap数据结构详解
Feb 17 Python
Python lxml模块安装教程
Jun 02 Python
Python 查看文件的编码格式方法
Dec 21 Python
删除python pandas.DataFrame 的多重index实例
Jun 08 Python
Python subprocess库的使用详解
Oct 26 Python
详解Python中pandas的安装操作说明(傻瓜版)
Apr 08 Python
Python实现的银行系统模拟程序完整案例
Apr 12 Python
python3 pygame实现接小球游戏
May 14 Python
基于多进程中APScheduler重复运行的解决方法
Jul 22 Python
python从内存地址上加载python对象过程详解
Jan 08 Python
pycharm安装及如何导入numpy
Apr 03 Python
浅谈Python从全局与局部变量到装饰器的相关知识
Jun 21 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
Linux编译升级php的详细方法
2013/11/04 PHP
php常用hash加密函数
2014/11/22 PHP
利用PHPStorm如何开发Laravel应用详解
2017/08/30 PHP
关于php开启错误提示的总结
2019/09/24 PHP
Thinkphp 框架配置操作之配置加载与读取配置实例分析
2020/05/15 PHP
用apply让javascript函数仅执行一次的代码
2010/06/27 Javascript
jquery之empty()与remove()区别说明
2010/09/10 Javascript
node.js中的fs.readlinkSync方法使用说明
2014/12/17 Javascript
NodeJs的优势和适合开发的程序
2016/08/14 NodeJs
Ajax与服务器(JSON)通信实例代码
2016/11/05 Javascript
jQuery内存泄露解决办法
2016/12/13 Javascript
jQuery编写textarea输入字数限制代码
2017/03/23 jQuery
基于bootstrap写的一点localStorage本地储存
2017/11/21 Javascript
[jQuery] 事件和动画详解
2019/03/05 jQuery
13 个npm 快速开发技巧(推荐)
2019/07/04 Javascript
Vue Router 实现动态路由和常见问题及解决方法
2020/03/06 Javascript
详解Vue Cli浏览器兼容性实践
2020/06/08 Javascript
JS PHP字符串截取函数实现原理解析
2020/08/29 Javascript
在Python中操作字符串之rstrip()方法的使用
2015/05/19 Python
Python在图片中添加文字的两种方法
2017/04/29 Python
Tornado高并发处理方法实例代码
2018/01/15 Python
python实现闹钟定时播放音乐功能
2018/01/25 Python
使用python实现简单五子棋游戏
2019/06/18 Python
CSS3属性选择符介绍
2008/10/17 HTML / CSS
HTML+CSS3 模仿Windows7 桌面效果
2010/06/17 HTML / CSS
css3实现六边形边框的实例代码
2019/05/24 HTML / CSS
德国旅游网站:weg.de
2018/06/03 全球购物
爱普生美国官网:Epson美国
2018/11/05 全球购物
毕业生的自我评价分享
2013/12/18 职场文书
给朋友的道歉信
2014/01/09 职场文书
2014年三八妇女节活动总结
2014/03/01 职场文书
建议书怎么写
2014/03/12 职场文书
村庄环境整治方案
2014/05/15 职场文书
体育个人工作总结
2015/02/09 职场文书
教师自荐信范文
2015/03/06 职场文书
2015年教研工作总结
2015/05/23 职场文书