项目介绍

taro-chatroom仿微信聊天室项目是基于taro+react+react-redux+ReactNative+taroPop等技术实现的taro版聊天App实例,支持编译到三端h5+小程序+RN端,实现了消息发送、表情大图,图片预览、长按菜单、红包、朋友圈等功能。

如下图:编译到多端效果:H5端/小程序/App端

技术实现:

编码/技术:Vscode + react/taro/redux/react-native

iconfont图标:阿里字体图标库

自定义导航栏Navigation + 底部Tabbar

弹窗组件:taroPop(基于Taro封装自定义模态框)

支持编译:H5端 + 小程序 + RN端

引入公共样式及状态管理

/**

* @desc Taro入口页面 app.jsx

* @about Q:282310962 wx: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 (

)

}

}

Taro.render(, document.getElementById('app'))

顶部导航栏/底部tabbar均为自定义组件,详情见:

Taro实现自定义导航栏+Tabbar菜单

弹窗插件是基于Taro自定义模态框组件,参看:

Taro仿ios/android对话框|模态框

taro表单验证|状态管理|本地存储

return (

{/* logo */}

欢迎来到Taro-Chatroom

{/* 表单 */}

登录

忘记密码

注册账号

)

由于taro中ReactNative端不支持同步存储,只能使用异步存储实现

/**

* @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.state

if(!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)

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)

}

...

}

对于一些兼容样式,不编译到RN端,则可通过如下代码包裹实现

/*postcss-pxtransform rn eject enable*/

/*postcss-pxtransform rn eject disable*/

taro滚动聊天至最底部

taro中实现聊天消息滚动到最底部,由于RN端不支持 createSelectorQuery,需要做兼容处理。

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表情符,实现比较简单,就不介绍了。

// 渲染消息记录

renderMsgTpl = (data) => {

return data.map((item, index) => (

{item.msgtype == 1 &&

{item.msg}

}

{item.msgtype == 2 &&

{item.msg}

}

{item.msgtype == 3 &&

{!item.isme ? : null}

{item.author}

{item.msg}

{item.isme ? : null}

}

{item.msgtype == 4 &&

{!item.isme ? : null}

{item.author}

{item.isme ? : null}

}

{item.msgtype == 5 &&

{!item.isme ? : null}

{item.author}

{item.isme ? : null}

}

...

))

}

...

// 点击聊天消息区域

msgPanelClicked = () => {

if(!this.state.showFootToolbar) return

this.setState({ showFootToolbar: false })

}

// 表情、选择区切换

swtEmojChooseView = (index) => {

this.setState({ showFootToolbar: true, showFootViewIndex: index })

}

// 底部表情tab切换

swtEmojTab = (index) => {

let lists = this.state.emotionJson

for(var i = 0, len = lists.length; i < len; i++) {

lists[i].selected = false

}

lists[index].selected = true

this.setState({ emotionJson: lists })

}

/* >>> 【编辑器/表情处理模块】------------------------------------- */

bindEditorInput = (e) => {

this.setState({

editorText: e.detail.value,

editorLastCursor: e.detail.cursor

})

}

bindEditorFocus = (e) => {

this.setState({ editorLastCursor: e.detail.cursor })

}

bindEditorBlur = (e) => {

this.setState({ editorLastCursor: e.detail.cursor })

}

handleEmotionTaped = (emoj) => {

if(emoj == 'del') return

// 在光标处插入表情

let { editorText, editorLastCursor } = this.state

let lastCursor = editorLastCursor ? editorLastCursor : editorText.length

let startStr = editorText.substr(0, lastCursor)

let endStr = editorText.substr(lastCursor)

this.setState({

editorText: startStr + `${emoj} ` + endStr

})

}

...

到这里taro开发聊天app就基本介绍完了,希望大家能喜欢~~

最后分享个基于Vue实例项目

vue+uniapp+vuex开发的仿抖音短视频|仿陌陌直播项目

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐