Taro realizes chatting, taro imitates wechat chat interface, taro+redux multi terminal instance

Keywords: Front-end Vue React Mobile

Recently, we have been exploring and developing multiple terminals, which has been used before uniapp+vue develops the project of multi terminal imitative buffeting / Momo live studio Today, I want to share the TaroChat project based on the taro+react multi terminal wechat like interface chat room, which also supports compiling to H5, applet and App.

Technical realization:

  • Framework technology: react / taro / Redux / react native
  • iconfont Icon: Ali Font Icon Library
  • Custom Navbar + Tabbar
  • Pop up component: taroPop (custom dialog box based on Taro encapsulation)
  • Support compilation: H5 + applet + App

/**
  * @desc   Taro Entry page app.jsx
  */

import Taro, { Component } from '@tarojs/taro'
import Index from './pages/index'

// Introducing status management redux
import { Provider } from '@tarojs/redux'
import { store } from './store'

// Import style
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'
    }
  }
  
  // The render() function in the App class has no practical effect
  // Do not modify this function
  render () {
    return (
      <Provider store={store}>
        <Index />
      </Provider>
    )
  }
}

Taro.render(<App />, document.getElementById('app'))

In order to unify the effect and enrich the function, the top navigation and the bottom tabbar adopt the custom component mode. As there is a sharing article before, it will not be introduced in detail here.

Top navigation bar / bottom tabbar component Taro multi terminal custom navigation bar Navbar+Tabbar instance

Taro custom Modal components refer to: Taro custom modal box component

taro login / registration form verification | redux status management | local storage

It's easy to get the input value of the form in taro, just use the onInput event directly

<Input placeholder="Please enter your mobile number/Nickname?" onInput={this.handleInput.bind(this, 'tel')} />
this.state = {
	tel: '',
	pwd: '',
}

handleInput = (key, e) => {
    this.setState({ [key]: e.detail.value })
}
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={require('../../../assets/taro.png')} mode="aspectFit" />
                    </View>
                    <Text className="auth-lgreg__slogan-text">Welcome to Taro-Chatroom</Text>
                </View>
                {/* form */}
                <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="Please enter your mobile number/Nickname?" onInput={this.handleInput.bind(this, 'tel')} />
                        </View>
                        <View className="auth-lgreg__forms-item">
                            <Input className="auth-lgreg__forms-iptxt flex1" placeholder="Please input a password" 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">Sign in</Text></TouchView>
                    </View>
                    <View className="auth-lgreg__forms-link">
                        <Text className="auth-lgreg__forms-link__nav">Forget password</Text>
                        <Text className="auth-lgreg__forms-link__nav" onClick={this.GoToRegister}>Registered account number</Text>
                    </View>
                </View>
            </View>
        </ScrollView>

        <TaroPop ref="taroPop" />
    </View>
)
/**
 * @tpl Login module
 */

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: 'Sign in'
    }
    constructor(props) {
        super(props)
        this.state = {
            tel: '',
            pwd: '',
        }
    }
    componentWillMount() {
        // Determine whether to log in
        storage.get('hasLogin').then(res => {
            if(res && res.hasLogin) {
                Taro.navigateTo({url: '/pages/index/index'})
            }
        })
    }
    // Submit Form 
    handleSubmit = () => {
        let taroPop = this.refs.taroPop
        let { tel, pwd } = this.state

        if(!tel) {
            taroPop.show({content: 'Mobile number cannot be empty', time: 2})
        }else if(!util.checkTel(tel)) {
            taroPop.show({content: 'Wrong format of mobile number', time: 2})
        }else if(!pwd) {
            taroPop.show({content: 'Password cannot be empty', time: 2})
        }else {
            // ... interface data
            ...
            
            storage.set('hasLogin', { hasLogin: true })
            storage.set('user', { username: tel })
            storage.set('token', { token: util.setToken() })

            taroPop.show({
                skin: 'toast',
                content: 'Login successfully',
                icon: 'success',
                time: 2
            })
            
            ...
        }
    }
    
    render () {
        ...
    }
}

const mapStateToProps = (state) => {
    return {...state.auth}
}

export default connect(mapStateToProps, {
    ...actions
})(Login)

taro scroll to the bottom of the chat message

H5 / applet can scroll to the bottom of chat by obtaining createSelectorQuery. Since RN does not support createSelectorQuery, it can only be processed in another compatible way.

// Scroll chat bottom
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)
}

This is the introduction of the development of the chat application by taro. We will continue to share the example project in the future. 😴😴

◆ vue chat room | h5+vue imitating wechat chat interface | vue imitating wechat

◆ react+redux imitation wechat client chat | web chat instance

Posted by bobbinsbro on Tue, 17 Dec 2019 05:06:23 -0800