You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js+Laravel实时聊天:是否有on leave/join/typing回调及用户总数方法?

嘿,刚好我之前做过Laravel+Vue的实时聊天功能,来给你详细说说这些需求怎么实现:

首先得明确:Vue.js本身并没有原生的on join/on leave/on typing回调函数,这些功能属于实时通信(WebSocket)层面的能力,我们通常会结合Laravel的广播系统(搭配Laravel Echo)来实现,常用的驱动有Pusher、Socket.io,或者Laravel官方推出的Reverb。

1. 实现on join(用户加入)、on leave(用户离开)回调

这两个功能依赖Laravel的存在频道(Presence Channels)——这种频道会自动追踪当前在线用户,所以自带了对应的监听回调:

在Vue组件中,你可以通过Laravel Echo监听存在频道的三个核心方法:

  • here():组件初始化时,获取当前频道的所有在线用户
  • joining():有新用户加入频道时触发
  • leaving():有用户离开频道时触发

示例代码:

export default {
    data() {
        return {
            roomId: 1, // 你的聊天房间ID
            onlineUsers: [],
            onlineUserCount: 0,
            currentUserId: 123 // 当前登录用户ID
        }
    },
    mounted() {
        // 监听指定的聊天房间存在频道
        Echo.join(`chat.room.${this.roomId}`)
            // 初始加载时获取在线用户列表
            .here((users) => {
                this.onlineUsers = users;
                this.onlineUserCount = users.length;
            })
            // 新用户加入时的回调
            .joining((user) => {
                this.onlineUsers.push(user);
                this.onlineUserCount++;
                // 可以在这里触发UI提示,比如弹出"XXX加入了聊天"
            })
            // 用户离开时的回调
            .leaving((user) => {
                this.onlineUsers = this.onlineUsers.filter(u => u.id !== user.id);
                this.onlineUserCount--;
                // UI提示"XXX离开了聊天"
            });
    }
}

2. 实现on typing(正在输入)功能

这个没有原生回调,需要我们自己手动实现,核心思路是:用户输入时发送事件到服务器,服务器广播该事件,其他用户监听;同时设置超时,用户停止输入一段时间后取消“正在输入”状态。

步骤1:Vue端处理输入事件

export default {
    data() {
        return {
            typingTimeout: null,
            typingUsers: []
        }
    },
    methods: {
        onInput() {
            // 发送"正在输入"请求到后端
            axios.post('/api/chat/typing', {
                roomId: this.roomId,
                userId: this.currentUserId
            });

            // 清除之前的超时定时器,重新设置3秒后发送"停止输入"事件
            clearTimeout(this.typingTimeout);
            this.typingTimeout = setTimeout(() => {
                axios.post('/api/chat/stop-typing', {
                    roomId: this.roomId,
                    userId: this.currentUserId
                });
            }, 3000);
        }
    },
    mounted() {
        // 监听后端广播的"用户正在输入"事件
        Echo.private(`chat.room.${this.roomId}`)
            .listen('UserTyping', (event) => {
                // 避免重复添加当前用户
                if (!this.typingUsers.some(u => u.id === event.user.id)) {
                    this.typingUsers.push(event.user);
                }
            })
            // 监听"用户停止输入"事件
            .listen('UserStoppedTyping', (event) => {
                this.typingUsers = this.typingUsers.filter(u => u.id !== event.user.id);
            });
    }
}

步骤2:Laravel端定义广播事件

你需要创建UserTyping和UserStoppedTyping两个事件,设置它们广播到对应的私有/存在频道,核心是让事件正确广播即可。

3. 获取在线用户总数

最简单的方式就是利用上面here()回调里的用户数组长度,或者在joining/leaving时更新计数变量(比如示例中的onlineUserCount)。

另外,你也可以直接通过Laravel Echo的频道实例获取在线用户数:

const chatChannel = Echo.join(`chat.room.${this.roomId}`);
this.onlineUserCount = chatChannel.members.length;

内容的提问来源于stack exchange,提问作者Pankaj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:05:49