用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 08 Python
在Python的框架中为MySQL实现restful接口的教程
Apr 08 Python
Python基于scrapy采集数据时使用代理服务器的方法
Apr 16 Python
Django URL传递参数的方法总结
Aug 28 Python
TensorFlow神经网络优化策略学习
Mar 09 Python
Jacobi迭代算法的Python实现详解
Jun 29 Python
在python plt图表中文字大小调节的方法
Jul 08 Python
python实现键盘输入的实操方法
Jul 16 Python
django的csrf实现过程详解
Jul 26 Python
Python 实现判断图片格式并转换,将转换的图像存到生成的文件夹中
Jan 13 Python
Python实现多线程下载脚本的示例代码
Apr 03 Python
详解python百行有效代码实现汉诺塔小游戏(简约版)
Oct 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
MySQL数据库转移,access,sql server 转 MySQL 的图文教程
2007/09/02 PHP
php连接函数implode与分割explode的深入解析
2013/06/26 PHP
详解php比较操作符的安全问题
2015/12/03 PHP
调用WordPress函数统计文章访问量及PHP原生计数器的实现
2016/03/21 PHP
解决tp5在nginx下修改配置访问的问题
2019/10/16 PHP
jQuery多级弹出菜单插件ZoneMenu
2014/12/18 Javascript
jQuery使用元素属性attr赋值详解
2015/02/27 Javascript
Javascript实现字数统计
2015/07/03 Javascript
在ASP.NET MVC项目中使用RequireJS库的用法示例
2016/02/15 Javascript
EasyUI闪屏EasyUI页面加载提示(原理+代码+效果图)
2016/02/21 Javascript
BootStrapTable 单选及取值的实现方法
2017/01/10 Javascript
Vue Cli3 创建项目的方法步骤
2018/10/15 Javascript
详解Vue前端生产环境发布配置实战篇
2019/05/07 Javascript
详解使用uni-app开发微信小程序之登录模块
2019/05/09 Javascript
使用异步controller与jQuery实现卷帘式分页
2019/06/18 jQuery
vue+django实现一对一聊天功能的实例代码
2019/07/17 Javascript
[06:49]2018DOTA2国际邀请赛寻真——VirtusPro傲视群雄
2018/08/12 DOTA
python实现最大子序和(分治+动态规划)
2019/07/05 Python
Pandas时间序列重采样(resample)方法中closed、label的作用详解
2019/12/10 Python
opencv3/C++图像像素操作详解
2019/12/10 Python
Python环境配置实现pip加速过程解析
2020/11/27 Python
网页布局中CSS样式无效的十个重要原因详解
2017/08/10 HTML / CSS
html5 css3 动态气泡按钮实例演示
2012/12/02 HTML / CSS
html5菜单折纸效果
2014/04/22 HTML / CSS
SneakerStudio英国:最佳运动鞋商店
2019/05/22 全球购物
Hanky Panky官方网站:内衣和睡衣
2019/07/25 全球购物
自我鉴定的范文
2013/10/03 职场文书
新春文艺演出主持词
2014/03/27 职场文书
2015年元旦活动总结
2014/05/09 职场文书
安全负责人任命书
2014/06/06 职场文书
统计专业自荐书
2014/07/06 职场文书
责任书格式
2019/04/18 职场文书
JVM入门之类加载与字节码技术(类加载与类的加载器)
2021/06/15 Java/Android
详细谈谈JavaScript中循环之间的差异
2021/08/23 Javascript
使用CSS自定义属性实现骨架屏效果
2022/06/21 HTML / CSS
python解析照片拍摄时间进行图片整理
2022/07/23 Python