react网页版聊天|仿微信、微博web版|react+pc端仿微信实例

一、项目介绍

基于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();
});

原文地址:https://www.cnblogs.com/xiaoyan2017/p/11106246.html

时间: 2024-10-21 14:50:11

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

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

等了好久,微信官方终于发布了.net的demo. 主要代码: /** * 生成直接支付url,支付url有效期为2小时,模式二 * @param productId 商品ID * @return 模式二URL */ public string GetPayUrl(string productId, string body, string attach, int total_fee, string goods_tag) { Log.Info(this.GetType().ToString(), "

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

Github StackChat 技术栈 写这个软件StackChat的主要目的是巩固练习Node和对React的实践,也是为了学习东西,所以选用了这些自己还没在项目里使用过的技术,边学变写 Electron React Material-UI React-Router Redux Express Socket.io MongoDB 现在已完成前端大部分界面的构建(无状态),所以记录一下 环境搭建 Create-React-App 利用React脚手架Create-React-App,再写入依赖

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

Github StackChat Redux学习回顾 Redux的主要功能就是管理复杂交错的State,比如需要讲state提升到顶层组件的场景中,使用Redux就很合适 Redux主要提供三个东西来进行状态管理 1. Action 表达要进行的动作,也就是通过view层触发,来进行派发来改变全局state action创建函数 也就是只返回一个action的函数 export const SignUpEmailChange = (value) => ({ type: 'SIGNUP_EMAIL

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

Github StackChat 用到的React-Router React-Router是React路由的解决方案之一,也可以使用别的库 安装 npm install react-router --save-dev 路由配置 react-router主要提供了几个组件来进行路由之间结构的组织 Router 所有路由组件的根 Route 路由组件 path属性 匹配路径 component属性 匹配路径渲染的组件 IndexRoute 配置默认页面 component 渲染的组件 React.r

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

Github StackChat 学习回顾 React和Electron结合 TypeError: fs.existsSync is not a function 在React组件里引入electron时候就会报这个错,主要原因是在React里不能引入Node.js的模块 解决方法 Webpack target属性 先展开Create-React-App所有配置 npm run eject 在webpack.config.js下添加配置 // other configs... module.ex

pc端引入微信公众号文章

最近做了一个小需求,结果坑特别多..... 需求是这样的,要给公司内部做一个微信公众号广告投票系统,整个项目就不多赘述了,有个小功能,要求是这样的: 点击某条记录后的“投票”按钮,在当前页面弹出弹窗显示文章内容(读取文章url,需要正确展示文字.图片.排版等),保持3分钟,这期间在当前页面上不可进行任何操作,不可投票也不可关闭文章.3分钟后,文章下方的投票区域可用,点击“提交”按钮时,校验所有项目是否都已选择,如果没有,则弹窗提示.提交完成后,状态更改为“已投票”(只是针对该用户,不针对该公众号

速递:PC端微信内测、小米或入股漫步者

       摘要:微信推出PC客户端,是不是将抢占QQ的最后一块领地?小米近期也有大举动,要收购(或大幅入股)漫步者. 微信PC端内测 有消息称腾讯内部正在进行PC版微信的内测,微信终于不在固守移动客户端,但是腾讯这样的举措,小编表示没有看懂. PC端的微信还是需要手机扫码才能登陆,这个感觉有点像是网页版.微信和QQ本来就是有点同质化的感觉,这次听闻推出了PC版,乍一听有点像"微信要抢占QQ的最后领地",其实不然. 小编分析原因有以下两点,①功能上微信和QQ是不同的,在QQ面板上你

喜大普奔 | 微信小程序支持PC端打开了

微信小程序可以在PC端打开啦 微信PC版发布了v2.7.0测试版,其中一个重磅的功能就是:支持打开聊天中分享的小程序 咖啡君这么喜欢尝鲜的人自然是在第一时间下载进行了体验 安装成功,会有功能更新说明 上边赫然写着"可以打开聊天中的小程序消息",一阵兴奋 将小程序分享给好友后,可以在PC端微信聊天窗口中看到卡片式的小程序界面跟手机端看到的样式保持了一致 点击卡片可以打开小程序,小程序会以新窗口的形式呈现,且在任务栏有独立的图标 大部分的操作跟手机端保持了一致,同时需要微信登陆的地方也支持

vue仿微信网页版|vue+web端聊天室|仿微信客户端vue版

一.项目介绍 基于Vue2.5.6+Vuex+vue-cli+vue-router+vue-gemini-scrollbar+swiper+elementUI等技术混合架构开发的仿微信web端聊天室——vueWebChat,实现了发送消息.表情(动图),图片.视频预览,右键菜单.截屏.截图可直接粘贴至文本框进行发送. 二.技术框架 MVVM框架:Vue2.5.6 状态管理:Vuex 页面路由:Vue-router iconfont图标:阿里巴巴字体图标库 自定义滚动条:vue-gemini-sc