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 相关文章推荐
js控制div及网页相关属性的代码
Dec 19 Javascript
jquery实现页面图片等比例放大缩小功能
Feb 12 Javascript
node.js中的fs.chownSync方法使用说明
Dec 16 Javascript
浅谈javascript中for in 和 for each in的区别
Apr 23 Javascript
JQuery和HTML5 Canvas实现弹幕效果
Jan 04 Javascript
angular bootstrap timepicker TypeError提示怎么办
Jun 13 Javascript
Vue封装一个简单轻量的上传文件组件的示例
Mar 21 Javascript
JS和Canvas实现图片的预览压缩和上传功能
Mar 30 Javascript
vue中的数据绑定原理的实现
Jul 02 Javascript
Layui数据表格跳转到指定页的实现方法
Sep 05 Javascript
JS实现轮播图效果
Jan 11 Javascript
ES6 Iterator遍历器原理,应用场景及相关常用知识拓展详解
Feb 15 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 文件缓存的性能测试
2010/04/25 PHP
php冒泡排序、快速排序、快速查找、二维数组去重实例分享
2014/04/24 PHP
php连接oracle数据库的核心步骤
2016/05/26 PHP
PHP微信网页授权的配置文件操作分析
2019/05/29 PHP
JavaScript 异步调用框架 (Part 6 - 实例 &amp; 模式)
2009/08/04 Javascript
JavaScript中的noscript元素属性位置及作用介绍
2013/04/11 Javascript
javascript实现在某个元素上阻止鼠标右键事件的方法和实例
2014/08/12 Javascript
js怎么判断flash swf文件是否加载完毕
2014/08/14 Javascript
Backbone中View之间传值的学习心得
2016/08/09 Javascript
深入理解vue.js双向绑定的实现原理
2016/12/05 Javascript
解决easyui日期时间框ie的兼容的问题
2018/03/01 Javascript
JS实现DOM节点插入操作之子节点与兄弟节点插入操作示例
2018/07/30 Javascript
pydev使用wxpython找不到路径的解决方法
2013/02/10 Python
对python numpy数组中冒号的使用方法详解
2018/04/17 Python
numpy.where() 用法详解
2019/05/27 Python
如何在Django配置文件里配置session链接
2019/08/06 Python
python多线程分块读取文件
2019/08/29 Python
python获取array中指定元素的示例
2019/11/26 Python
PyQt5中多线程模块QThread使用方法的实现
2020/01/31 Python
Python MySQL 日期时间格式化作为参数的操作
2020/03/02 Python
在keras下实现多个模型的融合方式
2020/05/23 Python
Keras之自定义损失(loss)函数用法说明
2020/06/10 Python
详解Python爬虫爬取博客园问题列表所有的问题
2021/01/18 Python
CSS3利用text-shadow属性实现多种效果的文字样式展现方法
2016/08/25 HTML / CSS
伦敦最著名的老字号百货公司:Selfridges(塞尔福里奇百货)
2016/07/25 全球购物
印度尼西亚在线时尚购物网站:ZALORA印尼
2016/08/02 全球购物
英国最大的电子零件及配件零售商:Partmaster
2017/04/24 全球购物
活动策划邀请函
2014/02/06 职场文书
房地产广告策划方案
2014/05/15 职场文书
党员群众路线承诺书
2014/05/20 职场文书
安全宣传标语
2014/06/10 职场文书
党员学习党的群众路线思想汇报(5篇)
2014/09/10 职场文书
部门群众路线教育实践活动对照检查材料思想汇报
2014/10/07 职场文书
退休教师追悼词
2015/06/23 职场文书
Redis分布式锁Redlock的实现
2021/08/07 Redis
使用Postman测试需要授权的接口问题
2022/06/21 Java/Android