一、项目介绍

基于react+react-dom+react-router-dom+redux+react-redux+webpack2.0+nodejs等技术混合开发的仿微信web端聊天室reactWebChat项目,实现了聊天记录右键菜单、发送消息、表情(动图),图片、视频预览,浏览器截图粘贴发送等功能。

二、技术选型

  • MVVM框架:react / react-dom
  • 状态管理:redux / react-redux
  • 页面路由:react-router-dom
  • 弹窗插件:wcPop
  • 打包工具:webpack 2.0
  • 环境配置:node.js + cnpm
  • 图片预览:react-photoswipe
  • 轮播滑动:swiper
{
"name": "react-webchat",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-redux": "^7.1.0",
"react-router-dom": "^5.0.1",
"react-scripts": "0.9.x",
"redux": "^4.0.1",
"redux-thunk": "^2.3.0"
},
"devDependencies": {
"jquery": "^2.2.3",
"react-custom-scrollbars": "^4.2.1",
"react-photoswipe": "^1.3.0",
"swiper": "^4.5.0"
},
"scripts": {
"start": "set HOST=localhost&& set PORT=3003 && react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}

◆ App主页面布局及路由配置:

render() {
let token = this.props.token
return (
<Router>
<div className="vChat-wrapper flexbox flex-alignc">
<div className="vChat-panel" /*style={{ backgroundImage: `url(${require("./assets/img/placeholder/vchat__panel-bg02.jpg")})` }}*/ >
<div className="vChat-inner flexbox">
{/* //顶部(最大、最小、关闭) */}
<Switch>
<WinBar />
</Switch> {/* //侧边栏 */}
<Switch>
<SideBar />
</Switch> {/* //主页面 */}
<div className="flex1 flexbox">
{/* 路由容器 */}
<Switch>
{
routers.map((item, index) => {
return <Route key={index} path={item.path} exact render={props => (
!item.meta || !item.meta.requireAuth ? (<item.component {...props} />) : (
token ? <item.component {...props} /> : <Redirect to={{pathname: '/login', state: {from: props.location}}} />
)
)} />
})
}
{/* 初始化页面跳转 */}
<Redirect push to="/index" />
</Switch>
</div>
</div>
</div>
</div>
</Router>
);
}

◆ react+react-redux配合状态管理:

import {combineReducers} from 'redux'
import defaultState from './state.js' function auth(state = defaultState, action) {
// 不同的action处理不同的逻辑
switch (action.type) {
case 'SET_TOKEN':
return {
...state, token: action.data
}
case 'SET_USER':
return {
...state, user: action.data
}
case 'SET_LOGOUT':
return {
user: null, token: null
}
default:
return { ...state }
}
}

◆ react页面路由配置:

/*
* @desc 页面地址路由js
*/ // 引入页面组件
import Login from '../views/auth/login'
import Register from '../views/auth/register'
import Index from '../views/index'
import Contact from '../views/contact'
import Uinfo from '../views/contact/uinfo'
import NewFriend from '../views/contact/new-friends'
import Ucenter from '../views/ucenter'
import News from '../views/news'
import NewsDetail from '../views/news/detail'; export default [
{
path: '/login', name: 'Login', component: Login,
meta: { hideSideBar: true },
},
{
path: '/register', name: 'Register', component: Register,
meta: { hideSideBar: true },
},
{
path: '/index', name: 'App', component: Index,
meta: { requireAuth: true },
},
{
path: '/contact', name: 'Contact', component: Contact,
meta: { requireAuth: true },
},
{
path: '/contact/uinfo', name: 'Uinfo', component: Uinfo,
},
{
path: '/contact/new-friends', name: 'NewFriend', component: NewFriend,
meta: { requireAuth: true },
},
{
path: '/news', name: 'News', component: News,
},
{
path: '/news/detail', name: 'NewsDetail', component: NewsDetail,
},
{
path: '/ucenter', name: 'Ucenter', component: Ucenter,
meta: { requireAuth: true },
}, // ...
]
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import {connect} from 'react-redux' import $ from 'jquery'
// 引入wcPop弹窗插件
import { wcPop } from '../../assets/js/wcPop/wcPop' // 引入自定义滚动条
import { Scrollbars } from 'react-custom-scrollbars' // 引入swiper
import Swiper from 'swiper'
import 'swiper/dist/css/swiper.css' // 引入图片预览组件react-photoswipe
import {PhotoSwipe} from 'react-photoswipe'
import 'react-photoswipe/lib/photoswipe.css' // 导入消息记录列表
import RecordList from '../../components/recordList'
// >>> 【编辑器+表情处理模块】------------------------------------------
// ...处理编辑器信息
function surrounds() {
setTimeout(function () { //chrome
var sel = window.getSelection();
var anchorNode = sel.anchorNode;
if (!anchorNode) return;
if (sel.anchorNode === $(".J__wcEditor")[0] ||
(sel.anchorNode.nodeType === 3 && sel.anchorNode.parentNode === $(".J__wcEditor")[0])) { var range = sel.getRangeAt(0);
var p = document.createElement("p");
range.surroundContents(p);
range.selectNodeContents(p);
range.insertNode(document.createElement("br")); //chrome
sel.collapse(p, 0); (function clearBr() {
var elems = [].slice.call($(".J__wcEditor")[0].children);
for (var i = 0, len = elems.length; i < len; i++) {
var el = elems[i];
if (el.tagName.toLowerCase() == "br") {
$(".J__wcEditor")[0].removeChild(el);
}
}
elems.length = 0;
})();
}
}, 10);
} // 定义最后光标位置
var _lastRange = null, _sel = window.getSelection && window.getSelection();
var _rng = {
getRange: function () {
if (_sel && _sel.rangeCount > 0) {
return _sel.getRangeAt(0);
}
},
addRange: function () {
if (_lastRange) {
_sel.removeAllRanges();
_sel.addRange(_lastRange);
}
}
} // 格式化编辑器包含标签
$("body").on("click", ".J__wcEditor", function(){
$(".wc__choose-panel").hide();
_lastRange = _rng.getRange();
});
$("body").on("focus", ".J__wcEditor", function(){
surrounds();
_lastRange = _rng.getRange();
});
$("body").on("input", ".J__wcEditor", function(){
surrounds();
_lastRange = _rng.getRange();
});

react网页版聊天|仿微信、微博web版|react+pc端仿微信实例的更多相关文章

  1. 【Egret】实现web页面操作PC端本地文件操作

    Egret 实现web页面操作PC端本地文件操作: http://edn.egret.com/cn/book/page/pid/181 //------------------------------ ...

  2. 微信浏览器的页面在PC端访问

    微信浏览器的页面在PC端访问: 普通的在微信浏览器看的页面如果不在php代码中解析一下,然后复制链接在PC打开就出现无法访问,因为它复制的地址是: https://open.weixin.qq.com ...

  3. PC端网站微信扫码登录

    需求分析:用户通过扫描我们网页的二维码,如果已经绑定我们平台的账户,即成功进入首页,否则提示先绑定个人微信账号. 1.绑定微信账号:是通过关注微信公众号实现绑定个人微信账号.首先通过后台接口获取到ti ...

  4. pc端用微信扫一扫实现微信第三方登陆

    官方文档链接 第一步:获取AppID  AppSecret (微信开发平台申请PC端微信登陆)   第二步:生成扫描二维码,获取code https://open.weixin.qq.com/conn ...

  5. c#版在pc端发起微信扫码支付

    等了好久,微信官方终于发布了.net的demo. 主要代码: /** * 生成直接支付url,支付url有效期为2小时,模式二 * @param productId 商品ID * @return 模式 ...

  6. 网页或WEB应用或PC端浏览器调用百度地图API

    今天在写微网页中遇见了调用百度地图这个问题:在一个容器中显示地图信息如图(设计图截图) 然后在网上查了接口:http://api.map.baidu.com/,就是这个东东,当然不止这个,还有几个必选 ...

  7. React开发实时聊天招聘工具 -第三章 React基础知识回顾

    function a (props) { return <h1>hello world{this.props.asd}</h1> } class a extends React ...

  8. Node.js实现PC端类微信聊天软件(二)

    Github StackChat 用到的React-Router React-Router是React路由的解决方案之一,也可以使用别的库 安装 npm install react-router -- ...

  9. Node.js实现PC端类微信聊天软件(五)

    Github StackChat 学习回顾 Socket.io 结合Express创建Socket.io服务器 const app = require('express')() const http ...

随机推荐

  1. 深入理解 Java 异常

  2. Java入门系列之类继承、抽象类、接口(五)

    前言 C#和Java关于类.抽象类.接口使用方式基本相似,只是对应关键字使用不同罢了,本节呢,我们只是对照C#和Java中关于这三个概念在具体使用时,看看有哪些不一样的地方. 类继承 C#和Java在 ...

  3. 10分钟彻底理解Redis的持久化机制:RDB和AOF

    作者:张君鸿 juejin.im/post/5d09a9ff51882577eb133aa9 什么是Redis持久化? Redis作为一个键值对内存数据库(NoSQL),数据都存储在内存当中,在处理客 ...

  4. Sql sever DateDiff 函数

    函数: DATEDIFF(datepart,startdate,enddate) 具体实例: --相差年数 结果0 SELECT DATEDIFF(yy,'2008-12-29','2008-12-1 ...

  5. Linux 磁盘分区、挂载

    一.分区介绍 mbr分区: 1.最多支持四个主分区 2.系统只能安装在主分区上 3.扩展分区要占一个主分区 4.mbr最大只支持2TB,但拥有最好的兼容性 gpt分区: 1.支持无限多个主分区(但操作 ...

  6. Implement Property Value Validation in Code 在代码中实现属性值验证(XPO)

    This lesson explains how to set rules for business classes and their properties. These rules are val ...

  7. 上传图片到七牛云(客户端 js sdk)

    大体思路 上一篇我们讲了如何通过服务器生成一个upToken,那前端拿到这个token后又该如何操作?在这里我给出一个相当简洁的版本. 首先我们来看一下上传的思路:调用七牛模块的upload方法,生成 ...

  8. SSM框架之Mybatis(6)动态SQL

    Mybatis(6)动态SQL 1.动态SQL 出现原因:有些时候业务逻辑复杂时,我们的 SQL 是动态变化的,此时在前面的学习中我们的 SQL 就不能满足要求了 1.1.if标签 我们根据实体类的不 ...

  9. 为什么AlertDialog要使用Builder来构建呢

    为什么 AlertDialog 使用Builder 模式呢? 首先说句废话,因为 AlertDialog 太过复杂,内部参数太多,然后不使用构建者模式那么 AlertDialog 的构造方法就可能是: ...

  10. HTML5播放视频,并使用ffmpeg对视频转编码

    网页加入视频可以用h5自带的video标签,这里用一个jQuery封装优化好的video视频组件videojs. videojs官方网站:https://docs.videojs.com/index. ...