当前位置: 首页 > news >正文

从零开始用react + tailwindcss + express + mongodb实现一个聊天程序(八) 聊天框用户列表

 简单画了个聊天框 就是咱们的HomePage.jsx

1.后端接口开发

     在server/src/index.js 新增 messagesRoutes

先引入 

import messageRoutes from './routes/message.route.js'

// 消息接口

app.use('/api/messages', messageRoutes)

在routes文件夹下新建message.route.js 有3个路由  左侧用户列表 点击用户获取消息列表  发送消息接口

在controllers下面 新建message.controller.js 先实现获取前端左侧边栏用户列表接口

import User from '../models/user.model.js';

export const getUsersForSidebar = async (req, res) => {

    try {

        // 获取当前登录用户的id

        const loggedInUserId = req.user._id;

        // 过滤用户 所有不等于当前用户id 的用户 .select 查询时排除password

        const filteredUsers = await User.find({ _id: { $ne: loggedInUserId } }).select("-password");

        res.status(200).json(filteredUsers);

    } catch (error) {

        console.log("error in getSidebarUsers: ");

        res.status(500).json({ message: error.message });

    }

}

// 点击左侧用户时,获取该用户与当前用户之间的聊天记录

export const getMessages = async (req, res) => {

}

// 发送消息

export const sendMessage = async (req, res) => {

}

2.测试接口

使用postman测试接口成功

3.前端页面

修改HomePage.jsx页面

 在components下面  新建3个组件 Sidebar NoChatSelected ChatBox

新建useChatStore.js

import {create} from "zustand";

import toast from "react-hot-toast"

import axiosInstance from "../lib/axios";

export const useChatStore = create((set, get) => ({

    users: [],

    selectedUser: null,

    isUserLoading:false,

    getUsers: async () => {

        set({isUserLoading: true});

       try {

            const res = await axiosInstance.get("/messages/users");

            set({users: res.data});

       } catch{

            toast.error("Error while fetching users");

       } finally{

            set({isUserLoading: false});

       }

    },

    // 选择一个联系人

    setSelectedUser: (user) => {

        set({selectedUser: user});

    }

}))

然后我们完善Sidebar.jsx

import { useEffect} from "react"
import { useChatStore } from "../store/useChatStore"
import {User} from "lucide-react"

const Sidebar = () => {
    const {getUsers,users,selectedUser, setSelectedUser,isUsersLoading} = useChatStore()

    useEffect(() => {
        getUsers()
    },[getUsers])

    if(isUsersLoading) return <div>Loading...</div>
  return (
    <aside className="h-full w-20 lg:w-72 border-r border-base-300 flex flex-col transition-all duration-200">
       <div className="border-b border-base-300 w-full p-5">
            <div className="flex items-center gap-2">
                <User  className="size-6" />
                <span className="font-medium hidden lg:block">联系人</span>
            </div>
            {/* 在线人员过滤 */}

       </div>

       <div className="overflow-y-auto w-full py-3">

         {users.map((user) =>(
            <button
                key={user._id}
                onClick={() => setSelectedUser(user)}
                className={`w-full p-3 flex items-center gap-3
                    hover:bg-base-300 transition-colors
                    ${selectedUser?._id===user._id ? "bg-base-300 ring-l ring-base-300":""}
                `}
            >
                <div className="relative mx-auto lg:mx-0">
                    <img 
                        src={user.profilePic || "https://picsum.photos/200" }
                        alt={user.userName}
                        className="size-12 object-cover rounded-full"
                    
                    />
                </div>

                {/* 用户信息 只在大屏显示 */}
                <div className="hidden lg:block text-left min-w-0">
                    <div className="font-medium truncate">{user.userName}</div>
                </div>
               
            </button>
         ))}
       </div>
    </aside>
  )
}

export default Sidebar

效果如下

 

好这篇就到这 下一篇 实现聊天功能

相关文章:

  • ByteBuddy
  • 联合省选 2025 游记
  • 【随手笔记】FFT+音乐频谱(二)
  • 工程化与框架系列(8)--持续集成实践
  • OpenFlow 全解析:前世今生与未来走向
  • 【极客时间】浏览器工作原理与实践-2 宏观视角下的浏览器 (6讲) - 2.5 渲染流程(上):HTML、CSS和JavaScript,是如何变成页面的?
  • leetcode第40题组合总和Ⅱ
  • Day32 第八章 贪心算法 part05
  • leetcode第17题求电话号码组合
  • 14. LangChain项目实战1——基于公司制度RAG回答机器人
  • MCAL-存储器驱动
  • 三次握手内部实现原理
  • easyExcel使用案例有代码
  • Nabla 分数阶微积分定义
  • 一次单精度天线的调优过滤
  • ZT21 【模板】差分
  • Python 面向对象编程-继承与多态
  • SyntaxError: positional argument follows keyword argument
  • CountDownLatch与CyclicBarrier使用及区别
  • Visual Studio Code集成MarsCode AI
  • 领卷网站怎么做的/seo推广话术
  • 中国邮政做特产的网站/百度引流推广哪家好
  • 贵州网站备案查询/全网推广网站
  • 柳州学校网站建设/比较好网站制作公司
  • h5网站开发/企业自助建站
  • 做网站可以赚钱吗/十堰seo排名公司