使用 PubNub、React.js 和 ES6 创建促进协作的 Web 应用程序

在之前的教程中,我演示了如何制作物联网设备原型,并使用 PubNub 的数据流网络从硬件传感器创建数据可视化。在本教程中,我将向您展示如何使用 PubNub 以及 React.js 和下一代 JavaScript ES6 构建实时协作 Web 应用程序,React.js 可以让您非常高效地操作 DOM。

使用 PubNub、React.js 和 ES6 创建促进协作的 Web 应用程序

现场演示:协作即时贴

我创建了同一个 Stickie Note 应用程序的两个版本:我在此 CodePen 上托管的版本使用 CDN 托管的 React 版本,另一个版本位于 GitHub 上,使用包管理器。在本教程中,我使用后者的“lite”版本。我将逐步介绍如何使用所有好东西来构建应用程序:npm、webpack、Babel for JSX 和 ES6!

先决条件

要继续操作,您需要:

  • 对 React 的基本了解
  • 了解 npm 包管理器,用于下载、安装和管理依赖项

  • 了解 webpack 模块构建器的工作知识,为浏览器捆绑 JavaScript 和其他资源(其工作方式类似于 grunt 或 gulp)

  • Node.js 和 npm 安装在您的计算机上

本教程不介绍如何开始使用 React。不过,您可以从许多其他优秀的 Envato Tuts+ 教程中了解更多信息。

你要做什么

您现在将使用 PubNub 构建一个简单的 Web 应用程序。 PubNub 是一个数据流网络 (DSN),提供全球基础设施,使您可以轻松构建和扩展实时应用程序和物联网设备。在这里,您将创建可共享的“便签”。这是应用程序的用户流程:

  1. 用户登录。
  2. 用户输入名称后,应用程序就会检索最近 50 条笔记(如果有)。

  3. 用户在便签板上输入内容,然后按回车键提交。

  4. 新的便签会与您的浏览器以及当前在线的所有其他浏览器上的其他便签一起显示。

现在,让我们开始吧!

安装软件包

在您应用的目录中,运行 npm init 来设置您的 package.json 文件,然后安装这些模块。

安装 webpack 模块构建器,它可以为前端编译、连接、缩小和压缩静态资源:

$ npm install webpack --save-dev

安装 webpack Web 服务器以运行本地服务器:

$ npm install webpack-dev-server --save-dev

安装 React、React DOM 和 CSS 动画附加组件:

$ npm install React React-dom React-addons-css-transition-group --save

安装 Babel 以使用 JSX 和 ES6。我们将在编译器 Babel 的帮助下使用 ES6 (ES 2015) 进行编写,这是下一代 JavaScript:

$ sudo npm install babel-loader babel-core babel-preset-es2015 babel-preset-react --save

安装 PubNub 以进行实时通信:

$ npm install pubnub --save

配置应用程序结构和Web服务器

创建与此类似的应用程序结构:

├── /app
│   ├── app.jsx
│   ├── stickie.jsx
│   ├── stickieList.jsx
├── /dist
├── /css
├── /images
├── /node_modules
├── index.html
├── package.json
└── webpack.config.js

并配置webpack.config.js

var webpack = require('webpack');
module.exports = {
  entry: './app/app.jsx',
  output: {path: './dist', filename: 'bundle.js'},
  watch: true,
  module: {...}
}

在此 GitHub 存储库上查看整个配置文件。

基本上,您正在设置一个入口文件(顶级文件)和输出目的地,在运行 webpack 命令后,所有 js(和 .jsx)文件将构建到单个文件中。此外,通过设置 watch: true,您可以确保 webpack 会监视您的文件更改并自动重建您的输出文件。

创建index.html文件

将脚本bundle.js包含在您的index.html文件中:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Collaborative Stickies</title>
    <link rel="stylesheet" href="css/style.css" />
  </head>
  <body>
    <section id="container"></section>
    <script src="dist/bundle.js"></script>
  </body>
</html>

此外,请注意正文中带有 id=”container” 的元素。这是您的 React 应用程序将插入的位置。

运行 Webpack 开发服务器

您可以使用以下命令运行开发服务器:

$ ./node_modules/.bin/webpack-dev-server

或者您可以通过添加以下行在 package.json 中进行设置:

"scripts": {
  "start": "webpack-dev-server"
},

这样您就可以使用 npm start 命令来运行服务器。

在浏览器中,转到 http://localhost:8080/webpack-dev-server/,您应该会看到您的应用程序(到目前为止是一个空白 HTML 页面)正在运行。

p>

使用 ES6 创建 React 组件

根据您在 webpack.config.js 中配置的入口点,在应用目录下打开一个新的 app.jsx 文件。从文件扩展名中可以看出,我们将使用 JSX JavaScript 语法扩展。

首先,导入 app.jsx 所需的模块和文件:

import React from 'react';
import ReactDOM from 'react-dom';
import StickieList from './stickieList';
import 'pubnub';

ES6 中新引入的 import 语句用于导入从外部模块或脚本导出的函数、对象或基元。

然后使用此 ES6 类声明定义一个类 CollabStickies,它扩展了 React.Component 类。这相当于 ES5 中的 React.createClass 方法:

class CollabStickies extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      stickieList: []
    }
  }

  componentWillMount() {
    … // will explain later
  }
...
  render() {
    return (
      <div>
        <StickieWritable username={this.props.username} color={this.props.color} />
        <StickieList stickieList={this.state.stickieList} />
      </div>
    );
  }
}

在构造函数中,您将设置此可变数据(stickieList 数组)的初始状态。每次收到新的便笺时,我们都会使用 this.setState() 更新数组。

在渲染函数中,使用 JSX 定义类似 HTML 模板的虚拟 DOM 元素。在本例中,包含自定义组件 StickieWritableStickieList。您可以将可变的 props 和 states 传递给要使用的组件。我们稍后将定义它们。

当你构建应用程序时,Babel 会将所有这些 ES6 和 JSX 语法转换为浏览器可以正常渲染的 ES5。

使用数据绑定渲染 DOM 节点

使用 ReactDOM.render()react-dom 包自带的),在 DOM 节点上渲染 CollabStickies 组件您的 HTML。

ReactDOM.render(
  <CollabStickies username={username} color={color} />,
  document.getElementById('container')
);

在这里,您会注意到用户名和颜色 props。此数据用于 CollabStickies 组件并传递给其子组件。

这些值应该从用户登录中获取;但是,为了简化本练习的应用程序,我们只需使用一个简单的 window.prompt() 来获取用户名,然后在加载应用程序时提供随机颜色的便笺。

var username = window.prompt('Your name');

const colors = ['yellow', 'pink', 'green', 'blue', 'purple'];
var color = colors[~~(Math.random() * colors.length)];

使用 PubNub、React.js 和 ES6 创建促进协作的 Web 应用程序

虽然我在这里使用的是浏览器原生的提示对话框,但实际上,我建议您创建另一个具有登录功能的 UI 组件,或者使用第三方对话框组件。您可以找到许多可重用的组件,例如 Elemental UI 的 Modal 和 Material UI 的 Dialog。

使用 PubNub 进行协作

现在,您将使用 PubNub 使应用程序具有协作性。

PubNub 是一个全球分布式数据流网络,可让您轻松构建实时应用程序。其核心功能是发布/订阅,可同时在多个用户之间发送和接收数据。

在此应用程序中,任何“登录”的人都可以在便签上发布消息并与其他用户共享。

使用 PubNub、React.js 和 ES6 创建促进协作的 Web 应用程序

要在您的应用中使用 PubNub,请确保 pubnub 模块已安装并导入到您的文件顶部。

正在初始化 PubNub

首先,您需要对其进行初始化以创建 Pubnub 对象的实例。您在实例化过程中需要 API 密钥,因此请注册 PubNub 以获取您自己的密钥。

const publish_key =  'pub-c-1d17120...'; // your pub key
const subscribe_key  = 'sub-c-85bdc...'; // your sub key

const pubnub = require('pubnub').init({                         
  publish_key   : publish_key,
  subscribe_key : subscribe_key,
  ssl: true,
  uuid: username
});

const channel = 'stickie-notes';

在这里,您将从“登录”过程中获得的用户名分配为 uuid,唯一标识符。 (在本练习中,我们将用户输入的任何字符串作为 uuid,但实际上,您需要一个真正的登录系统,以便每个 uuid 实际上是唯一的,没有重复!)

另外,请注意,对于这些全局常量值,我使用 ES6 const 声明,而不是 var 。在 ES6 中, const 充当只读变量,表示对值的常量引用。在后面的示例中,您还将看到新引入的 let,它是一个块作用域局部变量。

订阅消息

要创建可共享笔记应用程序,您将使用 PubNub 的 publish() 方法将您的笔记发送给每个人,而 subscribe() 让其他用户接收所有笔记。每次有人发布新笔记时,都会自动调用 subscribe() 方法。

在您的 React 应用程序中,让我们在 componentWillMount() 中调用 subscribe(),该函数在应用程序生命周期中发生初始渲染之前立即调用。

componentWillMount() {
  pubnub.subscribe({
    channel: channel,
    restore: true,
    connect: () => this.connect(),
    message: (m) => this.success(m)
  });
}

订阅方法是异步的,当每个操作成功完成时,会调用 message 回调。在回调中,我们通过设置 stickieList 数组的状态来更新便签列表,该数组在开头的构造函数中定义。

在 React 中,使用 setState 修改数据会自动更新视图。

success(m) { 
  let newList = [m].concat(this.state.stickieList);
  this.setState({stickieList: newList});
}

我们稍后将创建视图(UI 组件)。

在订阅回调中,您可能已经注意到带有箭头的有趣语法,=>。这称为箭头函数,其语法比 ES5 函数表达式更短。此外,此表达式按词法绑定 this 值。再次强调,通过 Babel,我们可以利用所有 ES6 的强大功能!

此外,我们还使用可选的 connect 回调到订阅方法来检索“历史记录”。当第一次建立与 PubNub 的连接时,这将获取过去的数据。

connect() { 
  pubnub.history({
    channel: channel,
    count: 50,
    callback: (m) => {
      m[0].reverse();
      for (var v of m[0]) {
        let newList = this.state.stickieList.concat(v);
        this.setState({stickieList: newList});
      }
    }
  });
}

history() 是 PubNub 存储和回放功能的一部分,在本例中,它从 PubNub 获取最后 50 条消息。在 success 回调中,也通过在此处设置 stickieList 数组的状态来更新视图。

发布消息

让我们创建一个类,StickieWritable。它是一个需要用户输入的便签组件。

它的渲染效果如下:

render() {
  return (
    <div className={'stickie-note writable ' + this.props.color}>
      <textarea type='text' placeholder='Your new note...' onKeyUp={this.handleTextChange.bind(this)} />
    </div>  
  );
}

textarea中,监听onKeyUp事件,每次触发该事件时,调用handleTextChange函数检查是否键是返回/输入键。请注意,我在调用函数时绑定了 this 。与 React.createClass()(React 的 ES5 方法创建类)不同,ES6 类不会自动将方法绑定到对象的实例,因此您需要自己绑定它。 (有几种不同的方法可以实现同一目标。)

handleTextChange函数中,将文本和用户数据发布到PubNub:

var data = {
  username: this.props.username,
  color: this.props.color,
  text: e.target.value,
  timestamp: Date.now()
};

pubnub.publish({
  channel: channel, 
  message: data, 
  callback: e.target.value = '' // resetting the text field
});

现在,当用户在记事本中键入一些文本并按回车键时,该消息将发送到 PubNub,并且所有其他用户同时接收该消息(在 1/4 秒内!)。

创建 UI 组件

应用程序 UI 由一些 UI 组件组成,如下所示:

使用 PubNub、React.js 和 ES6 创建促进协作的 Web 应用程序

1. CollabStickies

2. StickieWritable

3.贴纸

4。粘性列表

组件 1 和 2 已经处理完毕,所以让我们创建组件 3,一个单独的便签组件。

创建一个新文件stickie.jsx以使用 JSX 呈现 UI。与 StickieWritable 组件不同,这是一个只读 UI 组件,没有 UX 功能。它只有一个 render() 函数,可以使用 prop 数据绘制带有文本的便签。

基本上,每次用户从另一个用户收到新消息时,该消息都会在新的粘性组件中呈现。

import React from 'react';
import ReactDOM from 'react-dom';

export default class Stickie extends React.Component {
  render() {
    return (
      <div className={'stickie-note ' + this.props.color} >
        <p className='note'>{this.props.text}</p>
        <p className='username'>{this.props.username}</p>
      </div>  
    );
  }
}

接下来,我们将创建另一个 UI 组件 stickieList.jsx,它是该组件的容器,并包含一堆便签纸。

p>

动画组件

Stickie.jsx 和所有其他依赖项导入到 StickieList.jsx 中。在这里,我使用 ReactCSSTransitionGroup 插件和自定义 Web 字体。

import React from 'react';
import ReactDOM from 'react-dom';
import ReactCSSTransitionGroup from 'react/lib/ReactCSSTransitionGroup';
import Stickie from './stickie';
import webfontloader from 'webfontloader'

您可以使用 npm 安装 Web 字体加载器:

$ npm install webfontloader

然后您可以加载您选择的任何自定义字体。您可以查看源代码,了解如何导入自定义 Google 字体。

render() 中,使用 ES6 箭头函数和 map() 迭代数组,并使用 stickieList 进行渲染您刚刚创建的每个 Stickie 组件:

export default class StickieList extends React.Component {
  render() {
    let items = (this.props.stickieList || []).map((item) => 
      <li key={item.username + '-' + item.timestamp} >
        <div className="stickieWrapper">
          <Stickie text={item.text} color={item.color} username={item.username}/>
        </div>
      </li>);

    return (
      <ReactCSSTransitionGroup transitionName='animation' transitionEnterTimeout={500} transitionLeaveTimeout={500} component='ul' id="stickiesList">
        {items}
      </ReactCSSTransitionGroup>  
    )
  }
}

定义的组件可以使用 进行动画处理。设置 transitionName,您需要在 CSS 中使用它来定义动画样式。另外,请注意

  • 中的关键属性。当您使用 时,您需要为每个列表使用唯一的键来为每个组件设置动画。

    React 添加了额外的类名。例如,当你的 transitionName 是 'animation' 时,你还会有 'animation-enter', ' Animation-enter-active'、'animation-leave' 和 'animation-leave-active'。

    以下是 /css/style.css 中的代码:

    .animation-enter {
      opacity: 0.1;
      transform: scale(1.3);
      transition: all 1s ease-out;
     }
    .animation-enter.animation-enter-active {
      opacity: 1;
      transform: scale(1);
     }
    ...
    

    现在,您刚刚使用 React 和 PubNub 构建了一个实时协作应用程序!我希望您喜欢本教程!

    使用 PubNub、React.js 和 ES6 创建促进协作的 Web 应用程序

    您可以在此 GitHub 存储库中查看完整代码,包括 CSS。尽管在本教程中,我使用的是“lite”版本 app-lite.jsx,但您可以查看 app.jsx 了解更多功能。 p>

    如果您有兴趣构建更多实时应用程序,例如聊天应用程序、多人游戏、交易应用程序等,请前往 PubNub 并查找更多资源!

    想要更多反应吗?

    我们有一门专门针对尽可能提高您的 React 技能的课程。在本课程中,您将开始使用 React 和 Redux 构建现代 Web 应用程序。从零开始,您将使用这两个库来构建完整的 Web 应用程序。

    您将从最简单的架构开始,慢慢地逐个功能地构建应用程序。您将了解工具、减速器和路由等基本概念。您还将了解一些更高级的技术,例如智能组件和哑组件、纯组件和异步操作。最后,您将创建一个完整的抽认卡应用程序,用于通过间隔重复进行学习。

    有兴趣吗?看看吧!

    参考文献

    • PubNub:适用于物联网、移动和 Web 应用程序的全球实时数据流网络
    • PubNub JavaScript SDK 教程

    • React:用于创建用户界面的 JavaScript 库

    • ES6:ECMAScript 2015 语言规范

    • webpack:模块生成器

    以上就是使用 PubNub、React.js 和 ES6 创建促进协作的 Web 应用程序的详细内容,更多请关注编程之家其它相关文章!

    版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

  • 相关推荐


    阅读本文之前,分享大家一张图片,看图会发现JavaScript开发需求最高,占比达到42.84%,因此掌握JavaScript语言好工作就不愁啦,工欲善其事必先利其器,那么选择IDE来开发是至关重要的,本文指出常用的几款JavaScript IDE,分析其优缺点,如有不完善的请大家补充
    Promises是一种关于异步编程的规范,目的是将异步处理对象和处理规则进行规范化,为异步编程提供统一接口。本文简要的介绍了Promises的基础知识,希望我们我们能够更好的使用Promises,更轻松的编写代码。
    引子 Patrick Catanzariti 是一名Web开发工程师,最近他在 sitepoint 发表了《JavaScript Beyond the Web in 2014》,介绍了JavaScript在物联网中的应用,非常有意思。做为JavaScript的爱好者和从业者,我在这里把它翻译了,以飨
    小编吐血整理加上翻译,太辛苦了~求赞! 本文主要总结了JavaScript 常用功能总结,如一些常用的JS 对象,基本数据结构,功能函数等,还有一些常用的设计模式。 目录: 众所周知,JavaScript是动态的面向对象的编程语言,能够实现以下效果: 1. 丰富Web 网页功能 2. 丰富Web界面
    微软于今日(2015年12月10日)宣布即将开源Chakra核心控件,并改名为“ChakraCore”,该控件包含所有Edge JavaScript 引擎的所有核心功能。ChakraCore 将于下月发布在GitHub中。 Chakra提供了顶级的JavaScript处理功能,并具有非常强大的性能优
    通过统计数据库中的1000多个项目,我们发现在 JavaScript 中最常出现的错误有10个。本文会向大家介绍这些错误发生的原因以及如何防止。
    TypeScript 和 JavaScript 是目前项目开发中较为流行的两种脚本语言,我们已经熟知 TypeScript 是 JavaScript 的一个超集,但是 TypeScript 与 JavaScript 之间又有什么样的区别呢?在选择开发语言时,又该如何抉择呢?
    本文是2017年 JavaScript 框架回顾系列的最后的一篇文章,主要介绍 JavaScript 的后端框架情况。
    本文来源于多年的 JavaScript 编码技术经验,适合所有正在使用 JavaScript 编程的开发人员阅读。本文的目的在于帮助大家更加熟练的运用 JavaScript 语言来进行开发工作。
    对于前端开发人员来说,如果能够掌握交互式网页中的数据可视化技术,则是一项很棒的技能。当然,通过一些 JavaScript 的图表库也会使前端的数据可视化变得更加容易。
    几乎每隔一个星期,就有一个新的 JavaScript 库席卷网络社区!Web 社区日益活跃、多样,并在多个领域快速成长。想要研究每一个重要的 JavaScript 框架和库,是个不可能完成的任务。接下来,我会分享一些前端开发的最著名和最有影响力的框架和库。下面,就让我们一起来看看,顶级的 JavaS
    AngularJ.js 由google开发,2009年首次发布 很流行的前端框架 使用Angular.js创建第一个UI,成本很低 对于团队来说,AngularJ.js有许多很棒的工具可用 很适合创建一个快速、混合型复杂的解决方案 比起React,更合适于创建小型企业级应用 由Google负责维护基
    Javascript框架(以下简称框架)也被称为Javascript库,是一组包含丰富功能和函数的JavaScript代码集,能够帮助开发者快速完成Web设计和开发工作。随着Web社区的越发活跃,新的框架也层出不穷,目前流行的有:Angular、React、Vue.js和Knockout等。 面对如
    对于 JavaScript 社区来说,npm 的主要功能之一就是帮助开发者发掘所需的 npm Registry 中的库和框架。npm 强大的搜索功能能够帮助找到一组相关的软件包,同时其内置的的文档和使用统计信息,可以帮助开发者决定使用哪一种软件包。
    前言 SpreadJS作为一款性能出众的纯前端电子表格控件,自2015年发布以来,已经被广泛应用于各领域“在线Excel”数据管理项目中。NPM,作为管理Node.js库最有力的手段,解决了很多NodeJS代码部署的问题。 如今,为让您更方便的使用产品和更好地管理项目中的SpreadJS代码,我们已
    前一篇文章中,我们介绍了2017年 JavaScript 框架的整体情况。我们也了解到在众多的前端框架中,目前最为庞大又在快速增长的当属React了,本文就来重点介绍React的生态系统。
    ES2017标准已经于2017年6月份正式定稿了,并广泛支持最新的特性:异步函数。如果你曾经被异步JavaScript的逻辑困扰,这么新函数正是为你设计的。
    本文将会讨论10个优秀的支持JavaScript,HTML5和CSS开发,并且可以使用Markdown进行文档编写的文本编辑器。
    随着现在的编程语言功能越来越成熟、复杂,内存管理也容易被大家忽略。本文将会讨论JavaScript中的内存泄漏以及如何处理,方便大家在使用JavaScript编码时,更好的应对内存泄漏带来的问题。
    JavaScript 作为当前最为常见的直译式脚本语言,已经广泛应用于 Web 应用开发中。为了提高Web应用的性能,从 JavaScript 的性能优化方向入手,会是一个很好的选择。本文从加载、上下文、解析、编译、执行和捆绑等多个方面来讲解 JavaScript 的性能优化技巧,以便让更多的前端开