react+redux仿微信聊天界面


Posted in Javascript onJune 21, 2019

一、项目概况

基于react+react-dom+react-router-dom+redux+react-redux+webpack2.0+react-photoswipe+swiper等技术混合开发的手机端仿微信界面聊天室——reactChatRoom,实现了聊天记录下拉刷新、发送消息、表情(动图),图片、视频预览,打赏、红包等功能。

二、技术栈MVVM框架:

react / react-dom状态管理:redux / react-redux页面路由:react-router-dom弹窗插件:wcPop打包工具:webpack 2.0环境配置:node.js + cnpm图片预览:react-photoswipe轮播滑动:swiper

react+redux仿微信聊天界面

react+redux仿微信聊天界面

react+redux仿微信聊天界面

react+redux仿微信聊天界面

react+redux仿微信聊天界面

react+redux仿微信聊天界面

react+redux仿微信聊天界面

react+redux仿微信聊天界面

react+redux仿微信聊天界面

react+redux仿微信聊天界面

react+redux仿微信聊天界面

react+redux仿微信聊天界面

react+redux仿微信聊天界面

react+redux仿微信聊天界面

◆package.json依赖安装:

{
 "name": "react-chatroom",
 "version": "0.1.0",
 "private": true,
 "author": "andy",
 "dependencies": {
  "react": "^16.8.6",
  "react-dom": "^16.8.6",
  "react-redux": "^7.0.3",
  "react-router-dom": "^5.0.0",
  "react-scripts": "0.9.x",
  "redux": "^4.0.1"
 },
 "devDependencies": {
  "jquery": "^2.2.3",
  "react-loadable": "^5.5.0",
  "react-photoswipe": "^1.3.0",
  "react-pullload": "^1.2.0",
  "redux-thunk": "^2.3.0",
  "swiper": "^4.5.0",
  "webpack": "^1.13.1",
  "webpack-dev-server": "^1.12.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"
 }
}

◆ 入口页面index.js配置

/*
 * @desc 入口页面index.js
 */
import React from 'react';
import ReactDOM from 'react-dom';
// import {HashRouter as Router, Route} from 'react-router-dom'
import App from './App';
// 引入状态管理
import {Provider} from 'react-redux'
import {store} from './store'
// 导入公共样式
import './assets/fonts/iconfont.css'
import './assets/css/reset.css'
import './assets/css/layout.css'
// 引入wcPop弹窗样式
import './assets/js/wcPop/skin/wcPop.css'
// 引入js
import './assets/js/fontSize'
ReactDOM.render(
 <Provider store={store}>
  <App />
 </Provider>,
 document.getElementById('app')
);

◆ 页面App.js主模板

import React, { Component } from 'react';
import {HashRouter as Router, Route, Switch, Redirect} from 'react-router-dom'
import {connect} from 'react-redux'
import $ from 'jquery'
// 引入wcPop弹窗插件
import { wcPop } from './assets/js/wcPop/wcPop'
// 引入地址路由
import routers from './router'
// 导入顶部、底部tabbar
import HeaderBar from './components/header'
import TabBar from './components/tabbar'
class App extends Component {
 constructor(props){
  super(props)
  console.log('App主页面参数:\n' + JSON.stringify(props, null, 2))
 }
 render() {
  let token = this.props.token
  return (
   <Router>
    <div className="weChatIM__panel clearfix">
     <div className="we__chatIM-wrapper flexbox flex__direction-column">
      {/* 顶部 */}
      <Switch>
       <HeaderBar />
      </Switch>
      {/* 主页面 */}
      <div className="wcim__container flex1">
       {/* 路由容器 */}
       <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>
      {/* 底部tabbar */}
      <Switch>
       <TabBar />
      </Switch>
     </div>
    </div>
   </Router>
  );
 }
}
const mapStateToProps = (state) =>{
 return {
  ...state.auth
 }
}
export default connect(mapStateToProps)(App);

◆ react登录、注册模块 / react登录注册验证

import React, { Component } from 'react';
import { Link } from 'react-router-dom'
import { connect } from 'react-redux';
import * as actions from '../../store/action'
// 引入wcPop弹窗插件
import { wcPop } from '../../assets/js/wcPop/wcPop.js'
class Login extends Component {
  constructor(props) {
    super(props)
    this.state = {
      tel: '',
      pwd: '',
      vcode: '',
      vcodeText: '获取验证码',
      disabled: false,
      time: 0
    }
  }
  componentDidMount(){
    if(this.props.token){
      this.props.history.push('/')
    }
  }
  render() {
    return (
      <div className="wcim__lgregWrapper flexbox flex__direction-column">
        ......
      </div>
    )
  }
  // 提交表单
  handleSubmit = (e) => {
    e.preventDefault();
    var that = this
    this.state.tel = this.refs.tel.value
    this.state.pwd = this.refs.pwd.value
    this.state.vcode = this.refs.vcode.value
    if (!this.state.tel) {
      wcPop({ content: '手机号不能为空!', style: 'background:#ff3b30;color:#fff;', time: 2 });
    } else if (!checkTel(this.state.tel)) {
      wcPop({ content: '手机号格式不正确!', style: 'background:#ff3b30;color:#fff;', time: 2 });
    } else if (!this.state.pwd) {
      wcPop({ content: '密码不能为空!', style: 'background:#ff3b30;color:#fff;', time: 2 });
    } else if (!this.state.vcode) {
      wcPop({ content: '验证码不能为空!', style: 'background:#ff3b30;color:#fff;', time: 2 });
    } else {
      // 获取登录之前的页面地址
      let redirectUrl = this.props.location.state ? this.props.location.state.from.pathname : '/'
      // 设置token
      this.props.authToken(getToken())
      this.props.authUser(this.state.tel)
      wcPop({
        content: '注册成功!', style: 'background:#41b883;color:#fff;', time: 2,
        end: function () {
          that.props.history.push(redirectUrl)
        }
      });
    }
  }
  // 60s倒计时
  handleVcode = (e) => {
    e.preventDefault();
    this.state.tel = this.refs.tel.value
    if (!this.state.tel) {
      wcPop({ content: '手机号不能为空!', style: 'background:#ff3b30;color:#fff;', time: 2 });
    } else if (!checkTel(this.state.tel)) {
      wcPop({ content: '手机号格式不正确!', style: 'background:#ff3b30;color:#fff;', time: 2 });
    } else {
      this.state.time = 60
      this.state.disabled = true
      this.countDown();
    }
  }
  countDown = (e) => {
    if(this.state.time > 0){
      this.state.time--
      this.setState({
        vcodeText: '获取验证码(' + this.state.time + ')'
      })
      // setTimeout(this.countDown, 1000);
      setTimeout(() => {
        this.countDown()
      }, 1000);
    }else{
      this.setState({
        time: 0,
        vcodeText: '获取验证码',
        disabled: false
      })
    }
  }
}
const mapStateToProps = (state) => {
  return {
    ...state.auth
  }
}
export default connect(mapStateToProps, {
  authToken: actions.setToken,
  authUser: actions.setUser
})(Login)

总结

以上所述是小编给大家介绍的react+redux仿微信聊天界面,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Javascript 相关文章推荐
深入理解JavaScript系列(16) 闭包(Closures)
Apr 12 Javascript
js的for in循环和java里foreach循环的区别分析
Jan 28 Javascript
使用jquery动态加载Js文件和Css文件
Oct 24 Javascript
jquery关于事件冒泡和事件委托的技巧及阻止与允许事件冒泡的三种实现方法
Nov 27 Javascript
JavaScript文档碎片操作实例分析
Dec 12 Javascript
基于jQuery制作小图标上下滑动特效
Jan 18 Javascript
Vue中保存用户登录状态实例代码
Jun 07 Javascript
详谈表单格式化插件jquery.serializeJSON
Jun 23 jQuery
关于vue.js发布后路径引用的问题解决
Aug 15 Javascript
十个免费的web前端开发工具详细整理
Sep 18 Javascript
解决修复npm安装全局模块权限的问题
May 17 Javascript
深入理解使用Vue实现Context-Menu的思考与总结
Mar 09 Javascript
基于jQuery的时间戳与日期间的转化
Jun 21 #jQuery
jQuery事件委托代码实践详解
Jun 21 #jQuery
Vue.js中的extend绑定节点并显示的方法
Jun 20 #Javascript
微信小程序动态显示项目倒计时
Jun 20 #Javascript
微信小程序实现日期格式化和倒计时
Nov 01 #Javascript
微信小程序实现商城倒计时
Nov 01 #Javascript
微信小程序实现批量倒计时功能
Nov 01 #Javascript
You might like
PHP中构造函数和析构函数解析
2014/10/10 PHP
Joomla使用Apache重写模式的方法
2016/05/04 PHP
PHP常见字符串操作函数与用法总结
2019/03/04 PHP
静态页面的值传递(三部曲)
2006/09/25 Javascript
js 函数的副作用分析
2011/08/23 Javascript
js实现浏览器的各种菜单命令比如打印、查看源文件等等
2013/10/24 Javascript
JavaScript设计模式之外观模式实例
2014/10/10 Javascript
js计算时间差代码【包括计算,天,时,分,秒】
2016/04/26 Javascript
JavaScript入门教程之引用类型
2016/05/04 Javascript
JavaScript 函数的执行过程
2016/05/09 Javascript
Bootstrap源码解读媒体对象、列表组和面板(10)
2016/12/26 Javascript
JS Select下拉框(支持输入模糊查询)
2017/02/04 Javascript
Vue中组件之间数据的传递的示例代码
2017/09/08 Javascript
vue 本地服务不能被外部IP访问的完美解决方法
2018/10/29 Javascript
Vue移动端右滑屏幕返回上一页附源码下载
2019/06/26 Javascript
vue中的 $slot 获取插槽的节点实例
2019/11/12 Javascript
解决nuxt 自定义全局方法,全局属性,全局变量的问题
2020/11/05 Javascript
python2.7+selenium2实现淘宝滑块自动认证功能
2018/02/24 Python
Python通过属性手段实现只允许调用一次的示例讲解
2018/04/21 Python
使用memory_profiler监测python代码运行时内存消耗方法
2018/12/03 Python
解决Python 命令行执行脚本时,提示导入的包找不到的问题
2019/01/19 Python
matlab 计算灰度图像的一阶矩,二阶矩,三阶矩实例
2020/04/22 Python
python numpy库np.percentile用法说明
2020/06/08 Python
怎样从/向数据文件读/写结构
2014/11/23 面试题
Linux面试经常问的文件系统操作命令
2015/11/05 面试题
Python面试题集
2012/03/08 面试题
Java语言程序设计测试题改错题部分
2014/07/22 面试题
大学生就业自我鉴定
2013/10/26 职场文书
招聘单位介绍信
2014/01/14 职场文书
社区敬老月活动实施方案
2014/02/17 职场文书
员工试用期自我鉴定范文
2014/09/15 职场文书
酒店辞职书范文
2015/02/26 职场文书
党支部培养考察意见
2015/06/02 职场文书
2015年语言文字工作总结
2015/07/23 职场文书
药品销售员2015年终工作总结
2015/10/22 职场文书
Java中的继承、多态以及封装
2022/04/11 Java/Android