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

Posted xiaoyan2017

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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();
);

技术图片

 

以上是关于react网页版聊天|仿微信微博web版|react+pc端仿微信实例的主要内容,如果未能解决你的问题,请参考以下文章

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

react-native聊天室|RN版聊天App仿微信实例|RN仿微信界面

Androi:ListView+GridView实现仿微信微博朋友圈无焦点冲突

小程序版聊天室|聊天小程序|仿微信聊天界面小程序

web版仿微信聊天界面|h5仿微信电脑端案例开发

web微信