Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例

【Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例】学向勤中得,萤窗万卷书。这篇文章主要讲述Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例相关的知识,希望能为你提供帮助。
一、项目简述
taro-chatroom是基于Taro多端实例聊天项目,运用Taro+react+react-redux+taroPop+react-native等技术开发的仿微信App界面聊天室,实现了发送消息/emoj表情、gif表情大图、图片预览、发红包、动态圈等功能。
二、预览效果
编译到H5端、小程序、App端效果如下:(后续大图均为APP端)

Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例

文章图片

三、技术栈
  • 编码/技术:Vscode + react/taro/redux/RN
  • iconfont图标:阿里字体图标库
  • 自定义导航栏Navigation + 底部Tabbar
  • 弹窗组件:taroPop(基于Taro封装自定义模态框)
  • 支持编译:H5端 + 小程序 + App端
Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例

文章图片

Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例

文章图片

Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例

文章图片

Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例

文章图片

Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例

文章图片

Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例

文章图片

Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例

文章图片

Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例

文章图片

Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例

文章图片

Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例

文章图片

Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例

文章图片

Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例

文章图片

Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例

文章图片

/** * @descTaro入口页面 app.jsx
* @aboutQ:282310962wx:xy190310 */import Taro, { Component } from \'@tarojs/taro\' import Index from \'./pages/index\'// 引入状态管理redux import { Provider } from \'@tarojs/redux\' import { store } from \'./store\'// 引入样式 import \'./app.scss\' import \'./styles/fonts/iconfont.css\' import \'./styles/reset.scss\'class App extends Component { config = { pages: [ \'pages/auth/login/index\', \'pages/auth/register/index\', \'pages/index/index\', ... ], window: { backgroundTextStyle: \'light\', navigationBarBackgroundColor: \'#fff\', navigationBarTitleText: \'TaroChat\', navigationBarTextStyle: \'black\', navigationStyle: \'custom\' } }// 在 App 类中的 render() 函数没有实际作用 // 请勿修改此函数 render () { return ( < Provider store={store}> < Index /> < /Provider> ) } }Taro.render(< App /> , document.getElementById(\'app\'))

◆ Taro自定义顶部Navigation导航条 + Tabbar菜单
  • 由于项目需求,顶部导航栏/底部tabbar均为自定义组件,详情见:Taro多端自定义导航栏Navbar+Tabbar实例
  • 项目中用到的弹窗插件是基于Taro自定义模态框组件,参看:Taro自定义模态框组件
◆ 登录/注册验证模块
return ( < View className="taro__container flexDC bg-eef1f5"> < Navigation background=\'#eef1f5\' fixed /> < ScrollView className="taro__scrollview flex1" scrollY> < View className="auth-lgreg"> {/* logo */} < View className="auth-lgreg__slogan"> < View className="auth-lgreg__slogan-logo"> < Image className="auth-lgreg__slogan-logo__img" src=https://www.songbingjia.com/android/{require(/'../../../assets/taro.png\')} mode="aspectFit" /> < /View> < Text className="auth-lgreg__slogan-text"> 欢迎来到Taro-Chatroom< /Text> < /View> {/* 表单 */} < View className="auth-lgreg__forms"> < View className="auth-lgreg__forms-wrap"> < View className="auth-lgreg__forms-item"> < Input className="auth-lgreg__forms-iptxt flex1" placeholder="请输入手机号/昵称" onInput={this.handleInput.bind(this, \'tel\')} /> < /View> < View className="auth-lgreg__forms-item"> < Input className="auth-lgreg__forms-iptxt flex1" placeholder="请输入密码" password onInput={this.handleInput.bind(this, \'pwd\')} /> < /View> < /View> < View className="auth-lgreg__forms-action"> < TouchView onClick={this.handleSubmit}> < Text className="auth-lgreg__forms-action__btn"> 登录< /Text> < /TouchView> < /View> < View className="auth-lgreg__forms-link"> < Text className="auth-lgreg__forms-link__nav"> 忘记密码< /Text> < Text className="auth-lgreg__forms-link__nav" onClick={this.GoToRegister}> 注册账号< /Text> < /View> < /View> < /View> < /ScrollView> < TaroPop ref="taroPop" /> < /View> )

/** * @tpl 登录模块 */import Taro from \'@tarojs/taro\' import { View, Text, ScrollView, Image, Input, Button } from \'@tarojs/components\'import \'./index.scss\'import { connect } from \'@tarojs/redux\' import * as actions from \'../../../store/action\'...class Login extends Taro.Component { config = { navigationBarTitleText: \'登录\' } constructor(props) { super(props) this.state = { tel: \'\', pwd: \'\', } } componentWillMount() { // 判断是否登录 storage.get(\'hasLogin\').then(res => { if(res & & res.hasLogin) { Taro.navigateTo({url: \'/pages/index/index\'}) } }) } // 提交表单 handleSubmit = () => { let taroPop = this.refs.taroPop let { tel, pwd } = this.stateif(!tel) { taroPop.show({content: \'手机号不能为空\', time: 2}) }else if(!util.checkTel(tel)) { taroPop.show({content: \'手机号格式有误\', time: 2}) }else if(!pwd) { taroPop.show({content: \'密码不能为空\', time: 2}) }else { // ...接口数据 ...storage.set(\'hasLogin\', { hasLogin: true }) storage.set(\'user\', { username: tel }) storage.set(\'token\', { token: util.setToken() })taroPop.show({ skin: \'toast\', content: \'登录成功\', icon: \'success\', time: 2 })... } }render () { ... } }const mapStateToProps = (state) => { return {...state.auth} }export default connect(mapStateToProps, { ...actions })(Login)

taro本地存储使用的是异步存储,由于同步存储不支持RN端
Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例

文章图片

/** * @desc Taro本地存储 */import Taro from \'@tarojs/taro\'export default class Storage { static get(key) { return Taro.getStorage({ key }).then(res => res.data).catch(() => \'\') }static set(key, data){ return Taro.setStorage({key: key, data: data}).then(res => res) }static del(key){ Taro.removeStorage({key: key}).then(res => res) }static clear(){ Taro.clearStorage() } }

如不希望编译到RN端,使用如下包裹即可
  /*postcss-pxtransform rn eject enable*/ 
  /*postcss-pxtransform rn eject disable*/ 
对于一些RN端不兼容样式,边框、超过多行...,需特殊样式处理
/* *对于不兼容的样式,如RN不兼容border-right,可以通过mixin统一处理 *//** * RN 不支持针对某一边设置 style,即 border-bottom-style 会报错 * 那么 border-bottom: 1px 就需要写成如下形式: border: 0 style color; border-bottom-width: 1px; */ @mixin border($dir, $width, $style, $color) { border: 0 $style $color; @each $d in $dir { #{border-#{$d}-width}: $width; } }/** * NOTE RN 无法通过 text-overflow 实现省略号,这些代码不会编译到 RN 中 */ @mixin ellipsis { /*postcss-pxtransform rn eject enable*/ overflow: hidden; white-space: nowrap; text-overflow: ellipsis; /*postcss-pxtransform rn eject disable*/ }/** * NOTE 实现多行文本省略,RN 用 Text 标签的 numberOfLines={2},H5/小程序用 -webkit-line-clamp */ @mixin clamp($line) { /*postcss-pxtransform rn eject enable*/ display: -webkit-box; overflow: hidden; -webkit-line-clamp:$line; /* autoprefixer: ignore next */ -webkit-box-orient: vertical; /*postcss-pxtransform rn eject disable*/ }/** * 对于不能打包到 RN 的样式,可以用 postcss 方式引入 */ @mixin eject($attr, $value) { /*postcss-pxtransform rn eject enable*/ #{$attr}: $value; /*postcss-pxtransform rn eject disable*/ }

◆ Taro聊天实现消息滚动到底部
Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例

文章图片

在taro中实现聊天消息滚动到最底部,由于RN端不支持 createSelectorQuery,如是做了兼容处理。
Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例

文章图片

componentDidMount() { if(process.env.TARO_ENV === \'rn\') { this.scrollMsgBottomRN() }else { this.scrollMsgBottom() } }

// 滚动至聊天底部 scrollMsgBottom = () => { let query = Taro.createSelectorQuery() query.select(\'#scrollview\').boundingClientRect() query.select(\'#msglistview\').boundingClientRect() query.exec((res) => { // console.log(res) if(res[1].height > res[0].height) { this.setState({ scrollTop: res[1].height - res[0].height }) } }) } scrollMsgBottomRN = (t) => { let that = this this._timer = setTimeout(() => { that.refs.ScrollViewRN.scrollToEnd({animated: false}) }, t ? 16 : 0) }

聊天中表情使用的是emoj表情符,如果使用图片做表情也是可以,不过需要一些特殊匹配处理 :12)  [:高兴],使用emoj就相对简单些罢了。
Taro聊天室|react+taro仿微信聊天App界面|taro聊天实例

文章图片

// 渲染消息记录 renderMsgTpl = (data) => { return data.map((item, index) => ( < View key={index}> {item.msgtype == 1 & & < View className="msgitem msg__time"> < Text className="msg__text"> {item.msg}< /Text> < /View> }{item.msgtype == 2 & & < View className="msgitem msg__notice"> < Text className="msg__text"> {item.msg}< /Text> < /View> }{item.msgtype == 3 & & < View className="msgitem"> {!item.isme ? < View className="msg__avator"> < Image className="msg__avator-img" src=https://www.songbingjia.com/android/{item.avator} mode="aspectFit" /> < /View> : null} < View className={`msg__cntbox ${item.isme ? \'msg-me\' : \'msg-others\'}`}> < Text className="msg-author"> {item.author}< /Text> < View className={`msg__cnt ${item.isme ? \'msg__cnt-me\' : \'msg__cnt-others\'}`} onLongPress={this.handleLongPressMenu}> < Text className="msg__cnt-text"> {item.msg}< /Text> < /View> < /View> {item.isme ? < View className="msg__avator"> < Image className="msg__avator-img" src=https://www.songbingjia.com/android/{item.avator} mode="aspectFit" /> < /View> : null} < /View> }{item.msgtype == 4 & & < View className="msgitem"> {!item.isme ? < View className="msg__avator"> < Image className="msg__avator-img" src=https://www.songbingjia.com/android/{item.avator} mode="aspectFit" /> < /View> : null} < View className={`msg__cntbox ${item.isme ? \'msg-me\' : \'msg-others\'}`}> < Text className="msg-author"> {item.author}< /Text> < View className={`msg__cnt ${item.isme ? \'msg__cnt-me\' : \'msg__cnt-others\'} msg__lgface`} onLongPress={this.handleLongPressMenu}> < Image className="msg__lgface-img" src=https://www.songbingjia.com/android/{item.imgsrc} mode="widthFix" /> < /View> < /View> {item.isme ? < View className="msg__avator"> < Image className="msg__avator-img" src=https://www.songbingjia.com/android/{item.avator} mode="aspectFit" /> < /View> : null} < /View> }{item.msgtype == 5 & & < View className="msgitem"> {!item.isme ? < View className="msg__avator"> < Image className="msg__avator-img" src=https://www.songbingjia.com/android/{item.avator} mode="aspectFit" /> < /View> : null} < View className={`msg__cntbox ${item.isme ? \'msg-me\' : \'msg-others\'}`}> < Text className="msg-author"> {item.author}< /Text> < View className={`msg__cnt ${item.isme ? \'msg__cnt-me\' : \'msg__cnt-others\'} msg__picture`} onClick={this.handlePreviewPicture.bind(this, item.imgsrc)} onLongPress={this.handleLongPressMenu}> < Image className="msg__picture-img" src=https://www.songbingjia.com/android/{item.imgsrc} mode="widthFix" /> < /View> < /View> {item.isme ? < View className="msg__avator"> < Image className="msg__avator-img" src=https://www.songbingjia.com/android/{item.avator} mode="aspectFit" /> < /View> : null} < /View> }... < /View> )) }

以上就是taro开发聊天室的一些分享,今天就介绍到这里,希望能有些许的帮助~~

    推荐阅读