基于react18+react-vant仿微信聊天IM实例

项目介绍

react-chat 基于最新版react18.x hooksreact-vant移动端UI组件库实现仿制微信App聊天实例。

基于react18+react-vant仿微信聊天IM实例_第1张图片

技术框架

  • 开发工具:Vscode
  • 框架技术:react18+react-dom+vite4.x
  • UI组件库:react-vant (有赞react移动端UI库)
  • 状态管理:zustand^4.3.9
  • 路由管理:react-router-dom^6.14.2
  • className混合:clsx^2.0.0
  • 弹框组件:rcpop (基于react18 hooks自定义弹框组件)
  • 样式处理:sass^1.64.1

基于react18+react-vant仿微信聊天IM实例_第2张图片

项目结构

整个项目采用react18 hooks函数组件实现页面编码。

基于react18+react-vant仿微信聊天IM实例_第3张图片

基于react18+react-vant仿微信聊天IM实例_第4张图片

基于react18+react-vant仿微信聊天IM实例_第5张图片

基于react18+react-vant仿微信聊天IM实例_第6张图片

基于react18+react-vant仿微信聊天IM实例_第7张图片

基于react18+react-vant仿微信聊天IM实例_第8张图片

基于react18+react-vant仿微信聊天IM实例_第9张图片

基于react18+react-vant仿微信聊天IM实例_第10张图片

基于react18+react-vant仿微信聊天IM实例_第11张图片

基于react18+react-vant仿微信聊天IM实例_第12张图片

基于react18+react-vant仿微信聊天IM实例_第13张图片

基于react18+react-vant仿微信聊天IM实例_第14张图片

基于react18+react-vant仿微信聊天IM实例_第15张图片

基于react18+react-vant仿微信聊天IM实例_第16张图片

基于react18+react-vant仿微信聊天IM实例_第17张图片

基于react18+react-vant仿微信聊天IM实例_第18张图片

react18自定义移动端弹窗组件RcPop

rcpop 基于react18 hook自定义多功能弹框组件。整合了msg/alert/dialog/toast及android/ios弹窗效果。支持组件式+函数式调用方式。

基于react18+react-vant仿微信聊天IM实例_第19张图片

大家感兴趣,可以去看看这篇分享文章。

基于React18 Hooks实现移动端弹框组件RcPop

react18 hooks自定义导航栏+菜单栏组件

项目中顶部导航栏Navbar和底部菜单栏Tabbar组件均是使用react18自定义组件实现功能。

基于react18+react-vant仿微信聊天IM实例_第20张图片

基于react18+react-vant仿微信聊天IM实例_第21张图片

React18-Chat}
    fixed
    right={
        <>
            
            
        
    }
/>

navbar.jsx模板

function Navbar(props) {
    const {
        // 是否显示返回键
        back = true,
        // 自定义返回图标
        backIco,
        // 自定义返回文字
        backText,
        // 标题
        title,
        // 搜索区
        search,
        // 左侧自定义区
        left,
        // 右侧自定义区
        right,
        // 标题颜色
        color = '#fff',
        // 背景色
        bgcolor = '#139fcc',
        // 标题是否居中
        center,
        // 是否固定
        fixed,
        // 背景镂空透明
        transparent,
        // 层叠
        zIndex = 2023,

        className,
        ...rest
    } = props

    const handleBack = () => {
        window.history.back()
    }

    return (
        
{/* 返回 */} { isTrue(back) && (
{ backIco ? backIco : } {backText}
)} {left} {/* 标题 */} { !search &&
{title}
} {/* 搜索框 */} { search &&
{search}
} {/* 右侧 */}
{right}
) } export default Navbar

90a96c0bee52bfaf257a4a1815b3507a_1289798-20230815074211473-201147644.png

navbar.jsx模板

function Tabbar(props) {
    const {
        // 当前选项
        current = 0,
        // 背景色
        bgcolor = '#fff',
        // 颜色
        color = '#999',
        // 激活颜色
        activeColor = '#139fcc',
        // 是否固定
        fixed,
        // 背景镂空透明
        transparent,
        // 层叠
        zIndex = 2023,
        // tab选项
        tabs = [
            {
                path: '/',
                icon: 've-icon-message',
                title: '消息',
                badge: 2
            },
            {
                path: '/contact',
                icon: 've-icon-book',
                title: '通讯录',
                // dock: true,
                // dockBg: '#f90',
                // iconSize: '24px'
            },
            {
                path: '/my',
                icon: 've-icon-user',
                title: '我的',
                dot: true
            }
        ],
        onClick = () => {},

        className,
        ...rest
    } = props

    const [tabIndex, setTabIndex] = useState(current)

    const navigate = useNavigate()
    const location = useLocation()

    useEffect(() => {
        const { pathname } = location
        tabs.map((item, index) => {
            if(item.path == pathname) {
                setTabIndex(index)
            }
        })
    }, [current, tabs])

    const handleTabs = (index, item) => {
        setTabIndex(index)
        onClick?.(index)
        if(item?.path) {
            navigate(item?.path)
        }
    }

    return (
        
{ tabs.map((item, index) => { return (
handleTabs(index, item)}>
{ item.dock && } { item.icon && } { item.img && } { item.badge && {item.badge} } { item.dot && }
{item.title}
) })}
) } export default Tabbar

App.jsx主模板配置

import { HashRouter } from 'react-router-dom'

// 引入useRoutes集中式路由配置
import Router from './router'

// 引入fontSize
import '@assets/js/fontSize'

function App() {
    return (
        <>
            
                
            
        
    )
}

export default App

react-router-dom v6路由管理配置

基于react18+react-vant仿微信聊天IM实例_第22张图片

/**
 * react路由配置管理 by YXY Q:282310962
*/

import { lazy, Suspense } from 'react'
import { useRoutes, Outlet, Navigate } from 'react-router-dom'
import { Loading } from 'react-vant'

import { authStore } from '@/store/auth'

// 引入路由页面
import Login from '@views/auth/login'
import Register from '@views/auth/register'
const Index = lazy(() => import('@views/index'))
const Contact = lazy(() => import('@views/contact'))
const Uinfo = lazy(() => import('@views/contact/uinfo'))
const Chat = lazy(() => import('@views/chat/chat'))
const ChatInfo = lazy(() => import('@views/chat/info'))
const RedPacket = lazy(() => import('@views/chat/redpacket'))
const My = lazy(() => import('@views/my'))
const Fzone = lazy(() => import('@views/my/fzone'))
const Wallet = lazy(() => import('@views/my/wallet'))
const Setting = lazy(() => import('@views/my/setting'))
const Error = lazy(() => import('@views/404'))

// 加载提示
const SpinLoading = () => {
  return (
    
加载中...
) } // 延迟加载 const lazyload = children => { // React 16.6 新增了组件,让你可以“等待”目标代码加载,并且可以直接指定一个加载的界面 // 懒加载的模式需要我们给他加上一层 Loading的提示加载组件 return }>{children} } // 路由鉴权验证 const RouterAuth = ({ children }) => { const authState = authStore() return authState.isLogged ? ( children ) : ( ) } // 路由占位模板(类似vue中router-view) const RouterLayout = () => { return (
) } // useRoutes集中式路由配置 export const routerConfig = [ { path: '/', element: lazyload(), children: [ // 首页 // { path: '/', element: }, { index: true, element: }, // 通讯录模块 // { path: '/contact', element: lazyload() }, { path: '/contact', element: }, { path: '/uinfo', element: }, // 聊天模块 { path: '/chat', element: }, { path: '/chatinfo', element: }, { path: '/redpacket', element: }, // 我的模块 { path: '/my', element: }, { path: '/fzone', element: }, { path: '/wallet', element: }, { path: '/setting', element: }, // 404模块 path="*"不能省略 { path: '*', element: } ] }, // 登录/注册 { path: '/login', element: }, { path: '/register', element: } ] const Router = () => useRoutes(routerConfig) export default Router

react18状态管理Zustand

项目中使用的状态管理为Zustand。使用语法类似vue3 pinia状态管理插件。

基于react18+react-vant仿微信聊天IM实例_第23张图片

/**
 * Zustand状态管理,配合persist本地持久化存储
*/
import { create } from 'zustand'
import { persist, createJSONStorage } from 'zustand/middleware'

export const authStore = create(
    persist(
        (set, get) => ({
            isLogged: false,
            token: null,
            loggedData: (data) => set({isLogged: data.isLogged, token: data.token})
        }),
        {
            name: 'authState',
            // name: 'auth-store', // name of the item in the storage (must be unique)
            // storage: createJSONStorage(() => sessionStorage), // (optional) by default, 'localStorage' is used
        }
    )
)

Ending~~ 以上就是react18+zustand开发移动端聊天实例的一些分享。

https://segmentfault.com/a/1190000044012253
https://segmentfault.com/a/1190000043886272

你可能感兴趣的:(基于react18+react-vant仿微信聊天IM实例)