react-native聊天室|RN版聊天App仿微信实例|RN仿微信界面
一、前言
9月,又到开学的季节。为每个一直默默努力的自己点赞!最近都沉浸在reactnative原生app开发中,之前也有使用vue/react/angular等技术开发过聊天室项目,另外还使用RN技术做了个自定义模态弹窗rnPop组件。
一、项目简述
基于react+react-native+react-navigation+react-redux+react-native-swiper+rnPop等技术开发的仿微信原生App界面聊天室——RN_ChatRoom,实现了原生app启动页、AsyncStorage本地存储登录拦截、集成rnPop模态框功能(仿微信popupWindow弹窗菜单)、消息触摸列表、发送消息、表情(动图),图片预览,拍摄图片、发红包、仿微信朋友圈等功能。
二、技术点
- MVVM框架:react/react-native/react-native-cli
- 状态管理:react-redux/redux页面导航:react-navigationrn
- 弹窗组件:rnPop打包工具:webpack2.0轮播组件:react-native-swiper
- 图片/相册:react-native-image-picker
{ "name":"RN_ChatRoom", "version":"0.0.1", "aboutMe":"QQ:282310962、wx:xy190310", "dependencies":{ "react":"16.8.6", "react-native":"0.60.4" }, "devDependencies":{ "@babel/core":"^7.5.5", "@babel/runtime":"^7.5.5", "@react-native-community/async-storage":"^1.6.1", "@react-native-community/eslint-config":"^0.0.5", "babel-jest":"^24.8.0", "eslint":"^6.1.0", "jest":"^24.8.0", "metro-react-native-babel-preset":"^0.55.0", "react-native-gesture-handler":"^1.3.0", "react-native-image-picker":"^1.0.2", "react-native-swiper":"^1.5.14", "react-navigation":"^3.11.1", "react-redux":"^7.1.0", "react-test-renderer":"16.8.6", "redux":"^4.0.4", "redux-thunk":"^2.3.0" }, "jest":{ "preset":"react-native" } }
◆App全屏幕启动页splash模板
react-native如何全屏启动?设置StatusBar顶部条背景为透明translucent={true},并配合RN动画Animated
/** *@desc启动页面 */ importReact,{Component}from'react' import{StatusBar,Animated,View,Text,Image}from'react-native' exportdefaultclassSplashextendsComponent{ constructor(props){ super(props) this.state={ animFadeIn:newAnimated.Value(0), animFadeOut:newAnimated.Value(1), } } render(){ return(RN-ChatRoomv1.0.0 ) } componentDidMount(){ //判断是否登录 storage.get('hasLogin',(err,object)=>{ setTimeout(()=>{ Animated.timing( this.state.animFadeOut,{duration:300,toValue:0} ).start(()=>{ //跳转页面 util.navigationReset(this.props.navigation,(!err&&object&&object.hasLogin)?'Index':'Login') }) },1500); }) } }
◆RN本地存储技术async-storage
/** *@desc本地存储函数 */ importAsyncStoragefrom'@react-native-community/async-storage' exportdefaultclassStorage{ staticget(key,callback){ returnAsyncStorage.getItem(key,(err,object)=>{ callback(err,JSON.parse(object)) }) } staticset(key,data,callback){ returnAsyncStorage.setItem(key,JSON.stringify(data),callback) } staticdel(key){ returnAsyncStorage.removeItem(key) } staticclear(){ AsyncStorage.clear() } } global.storage=Storage
声明全局global变量,只需在App.js页面一次引入、多个页面均可调用。
storage.set('hasLogin',{hasLogin:true})
storage.get('hasLogin',(err,object)=>{...})
◆App主页面模板及全局引入组件
importReact,{Fragment,Component}from'react' import{StatusBar}from'react-native' //引入公共js import'./src/utils/util' import'./src/utils/storage' //导入样式 import'./src/assets/css/common' //导入rnPop弹窗 import'./src/assets/js/rnPop/rnPop.js' //引入页面路由 importPageRouterfrom'./src/router' classAppextendsComponent{ render(){ return({/* ) } } exportdefaultApp*/} {/*页面*/} {/*弹窗模板*/}
◆react-navigation页面导航器/地址路由、底部tabbar
由于react-navigation官方顶部导航器不能满足需求,如是自己封装了一个,功能效果有些类似微信导航。
exportdefaultclassHeaderBarextendsComponent{ constructor(props){ super(props) this.state={ searchInput:'' } } render(){ /** *更新 *@param{navigation|页面导航} *@param{title|标题} *@param{center|标题是否居中} *@param{search|是否显示搜索} *@param{headerRight|右侧Icon按钮} */ let{navigation,title,bg,center,search,headerRight}=this.props return({/*返回*/} {/*标题*/} {!search&¢er? :null} { search? ( {this.setState({searchInput:text})}}style={styles.barSearchText}placeholder='搜索'placeholderTextColor='rgba(255,255,255,.6)'/> ) : ( {title? {title}:null} ) } {/*右侧*/} { !headerRight?null:headerRight.map((item,index)=>{ return( item.press?item.press(this.state.searchInput):null}> { item.type==='iconfont'?item.title:( typeofitem.title==='string'? {`${item.title}`} : ) } {/*圆点*/} {item.badge? {item.badge}:null} {item.badgeDot? :null} ) }) } ) } goBack=()=>{ this.props.navigation.goBack() } }
//创建底部TabBar consttabNavigator=createBottomTabNavigator( //tabbar路由(消息、通讯录、我) { Index:{ screen:Index, navigationOptions:({navigation})=>({ tabBarLabel:'消息', tabBarIcon:({focused,tintColor})=>() }) }, Contact:{ screen:Contact, navigationOptions:{ tabBarLabel:'通讯录', tabBarIcon:({focused,tintColor})=>( 12 ) } }, Ucenter:{ screen:Ucenter, navigationOptions:{ tabBarLabel:'我', tabBarIcon:({focused,tintColor})=>( ) } } }, //tabbar配置 { ... } )
◆RN聊天页面功能模块
1、表情处理:原本是想着使用图片表情gif,可是在RN里面textInput文本框不能插入图片,只能通过定义一些特殊字符:66:(:12[奋斗]解析表情,处理起来有些麻烦,而且图片多了影响性能,如是就改用emoj表情符。
faceList:[ { nodes:[ '