用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 相关文章推荐
pymssql ntext字段调用问题解决方法
Dec 17 Python
python 获取本机ip地址的两个方法
Feb 25 Python
Python中集合的内建函数和内建方法学习教程
Aug 19 Python
Python编码爬坑指南(必看)
Jun 10 Python
深入解答关于Python的11道基本面试题
Apr 01 Python
django允许外部访问的实例讲解
May 14 Python
python实现连续图文识别
Dec 18 Python
通过shell+python实现企业微信预警
Mar 07 Python
pytorch打印网络结构的实例
Aug 19 Python
python 有效的括号的实现代码示例
Nov 11 Python
opencv 图像加法与图像融合的实现代码
Jul 08 Python
python爬虫中的url下载器用法详解
Nov 30 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设计模式 php实现桥梁模式(bridge)
2015/12/07 PHP
JavaScript使用prototype定义对象类型
2007/02/07 Javascript
jQuery 处理网页内容的实现代码
2010/02/15 Javascript
jQuery学习笔记之DOM对象和jQuery对象
2010/12/22 Javascript
IE6下opacity与JQuery的奇妙结合
2013/03/01 Javascript
window.showModalDialog参数传递中含有特殊字符的处理方法
2013/06/06 Javascript
node.js中的fs.lchmodSync方法使用说明
2014/12/16 Javascript
js实现遍历含有input的table实例
2015/12/07 Javascript
jQuery层次选择器用法示例
2016/09/09 Javascript
解析如何利用iframe标签以及js制作时钟
2016/12/08 Javascript
Bootstrap源码解读表单(2)
2016/12/22 Javascript
Vue异步组件使用详解
2017/04/08 Javascript
JS文件中加载jquery.js的实例代码
2018/05/05 jQuery
使用post方法实现json往返传输数据的方法
2019/03/30 Javascript
JavaScript 作用域scope简单汇总
2019/10/23 Javascript
JavaScript实现图片放大预览效果
2020/11/02 Javascript
老生常谈Python进阶之装饰器
2017/05/11 Python
Python程序员面试题 你必须提前准备!
2018/01/16 Python
python爬虫实例详解
2018/06/19 Python
Sanic框架路由用法实例分析
2018/07/16 Python
python读取图片任意范围区域
2019/01/23 Python
python 定时任务去检测服务器端口是否通的实例
2019/01/26 Python
python openpyxl使用方法详解
2019/07/18 Python
appium+python adb常用命令分享
2020/03/06 Python
Python3如何实现Win10桌面自动切换
2020/08/11 Python
CSS3哪些新特性值得称赞
2016/03/02 HTML / CSS
美国男女折扣服饰百货连锁店:Stein Mart
2017/05/02 全球购物
公司面试感谢信
2014/02/01 职场文书
信电学院毕业生自荐书
2014/05/24 职场文书
普通党员对照检查材料
2014/08/28 职场文书
python中sys模块的介绍与实例
2021/04/17 Python
python爬虫之利用selenium模块自动登录CSDN
2021/04/22 Python
MongoDB使用profile分析慢查询的步骤
2021/04/30 MongoDB
Windows11性能真的上涨35%? 桌面酷睿i9实测结果公开
2021/11/21 数码科技
MySQL数据库查询进阶之多表查询详解
2022/04/08 MySQL
Centos系统通过Docker安装并搭建MongoDB数据库
2022/04/12 MongoDB