react网页版聊天|仿微信、微博web版|react+pc端仿微信实例
发布时间:2020-12-15 16:16:58 所属栏目:百科 来源:网络整理
导读:一、项目介绍 基于react+react-dom+react-router-dom+redux+react-redux+webpack2.0+nodejs等技术混合开发的仿微信web端聊天室reactWebChat项目,实现了聊天记录右键菜单、发送消息、表情(动图),图片、视频预览,浏览器截图粘贴发送等功能。 二、技术选型 M
一、项目介绍基于react+react-dom+react-router-dom+redux+react-redux+webpack2.0+nodejs等技术混合开发的仿微信web端聊天室reactWebChat项目,实现了聊天记录右键菜单、发送消息、表情(动图),图片、视频预览,浏览器截图粘贴发送等功能。 二、技术选型
{ "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,{ path: ‘/index‘,name: ‘App‘,component: Index,meta: { requireAuth: true },{ path: ‘/contact‘,name: ‘Contact‘,component: Contact,{ path: ‘/contact/uinfo‘,name: ‘Uinfo‘,component: Uinfo,{ path: ‘/contact/new-friends‘,name: ‘NewFriend‘,component: NewFriend,{ path: ‘/news‘,name: ‘News‘,component: News,{ path: ‘/news/detail‘,name: ‘NewsDetail‘,component: NewsDetail,{ path: ‘/ucenter‘,name: ‘Ucenter‘,component: Ucenter,// ... ] 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",function(){ surrounds(); _lastRange = _rng.getRange(); }); $("body").on("input",function(){ surrounds(); _lastRange = _rng.getRange(); }); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- c – 用于运算符重载的friend关键字
- ruby-on-rails – 如何在Heroku上浏览我的DataBase记录
- 关于solr schema.xml 和solrconfig.xml的解释
- ruby-on-rails – 多次运行rake db:seed而不创建重复记录?
- c – 无法为整数生成全范围的随机数
- XML解析和安卓单元测试框架
- vue2.0 element-ui中el-upload的before-upload方法返回fal
- XML类及XmlSerializer 的使用
- Plsql Developer连接Oracle时出现Could not initialize oci
- OpenCV训练分类器制作xml文档