|
项目简介:
TaroChatroom项目是基于taro+react+redux+reactNative等技术跨端实践仿微信界面聊天室,实现了消息发送、动态表情、图片预览、长按菜单、发红包、朋友圈等功能。支持编译到H5、小程序、App端。
编译效果:
实现技术:
- 编码/技术:Vscode + react/taro/redux/react-native
- iconfont图标:阿里字体图标库
- 自定义导航栏Navigation + 底部Tabbar
- 弹窗组件:taroPop(基于Taro封装自定义模态框)
- 支持编译:H5端 + 小程序 + RN端
入口页面、页面路径配置
- /**
- * @desc Taro入口页面 app.jsx
- */
- 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表单验证|状态管理|存储实现
- 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">欢迎来到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>
- )
复制代码 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)
复制代码 对于一些兼容样式,不编译到RN端,则可通过如下代码包裹实现
/*postcss-pxtransform rn eject enable*/
/*postcss-pxtransform rn eject disable*/
taro中实现聊天消息滚动到最底部,由于RN端不支持 createSelectorQuery,需要做兼容处理
- // 滚动至聊天底部
- 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)
- }
复制代码
- // 点击聊天消息区域
- 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
- })
- }
- ...
复制代码
ok,到这里taro开发聊天app就基本介绍完了,后续会继续放送实例项目,希望大家能喜欢~~
最后分享个基于Vue实例项目
vue+uniapp+vuex开发的仿抖音短视频|仿陌陌直播项目
|
|