用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 getopt模块处理命令行选项实例
May 13 Python
Python自定义装饰器原理与用法实例分析
Jul 16 Python
Python实现将Excel转换成为image的方法
Oct 23 Python
使用python对文件中的数值进行累加的实例
Nov 28 Python
python 设置输出图像的像素大小方法
Jul 04 Python
django 扩展user用户字段inlines方式
Mar 30 Python
python实现处理mysql结果输出方式
Apr 09 Python
关于Python解包知识点总结
May 05 Python
django 解决model中类写不到数据库中,数据库无此字段的问题
May 20 Python
Python实现FTP文件定时自动下载的步骤
Dec 19 Python
python3中celery异步框架简单使用+守护进程方式启动
Jan 20 Python
利用Python将list列表写入文件并读取的方法汇总
Mar 25 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面向对象程序设计之类与反射API详解
2016/12/02 PHP
PHP检查端口是否可以被绑定的方法示例
2018/08/09 PHP
css把超出的部分显示为省略号的方法兼容火狐
2008/07/23 Javascript
JS 动态获取节点代码innerHTML分析 [IE,FF]
2009/11/30 Javascript
jquery $.fn $.fx是什么意思有什么用
2013/11/04 Javascript
javascript实现了照片拖拽点击置顶的照片墙代码
2015/04/03 Javascript
jQuery在线选座位插件seat-charts特效代码分享
2015/08/27 Javascript
详解Bootstrap按钮
2016/01/04 Javascript
jquery-mobile表单的创建方法详解
2016/11/23 Javascript
vue.js父组件使用外部对象的方法示例
2017/04/25 Javascript
基于jquery trigger函数无法触发a标签的两种解决方法
2018/01/06 jQuery
浅谈Vue.js路由管理器 Vue Router
2018/08/16 Javascript
VUE-cli3使用 svg-sprite-loader
2018/10/20 Javascript
关于Vue源码vm.$watch()内部原理详解
2019/04/26 Javascript
微信小程序如何调用图片接口API并居中显示
2019/06/29 Javascript
VUE解决 v-html不能触发点击事件的问题
2019/10/28 Javascript
vue element-ul实现展开和收起功能的实例代码
2020/11/25 Vue.js
python不带重复的全排列代码
2013/08/13 Python
TensorFlow深度学习之卷积神经网络CNN
2018/03/09 Python
Python中return self的用法详解
2018/07/27 Python
详解Python3 基本数据类型
2019/04/19 Python
Django如何开发简单的查询接口详解
2019/05/17 Python
python列表生成器迭代器实例解析
2019/12/19 Python
python小程序基于Jupyter实现天气查询的方法
2020/03/27 Python
Python进行统计建模
2020/08/10 Python
python创建文本文件的简单方法
2020/08/30 Python
Python+logging输出到屏幕将log日志写入文件
2020/11/11 Python
基于Django快速集成Echarts代码示例
2020/12/01 Python
浅析数据存储的三种方式 cookie sessionstorage localstorage 的异同
2020/06/04 HTML / CSS
高档奢华时装在线目的地:FORWARD by elyse walker
2017/10/16 全球购物
2014元旦晚会策划方案
2014/02/19 职场文书
晚归检讨书
2014/02/19 职场文书
妈妈活动方案
2014/08/15 职场文书
2015届大学生就业推荐表自我评价
2014/09/27 职场文书
中秋联欢会主持词
2015/07/04 职场文书
python 使用Tensorflow训练BP神经网络实现鸢尾花分类
2021/05/12 Python