Vue3实战:构建现代化实时聊天应用 | Composition API与WebSocket深度应用

2025-08-22 0 831


登录聊天室

{{ message.username.charAt(0).toUpperCase() }}
{{ message.username }}
{{ formatTime(message.timestamp) }}
{{ message.text }}

{{ isConnected ? ‘已连接’ : ‘连接断开’ }}

const { createApp, ref, reactive, computed, onMounted, onUnmounted, watch, nextTick } = Vue;
const { createPinia, defineStore } = Pinia;

// 创建Pinia实例
const pinia = createPinia();

// 用户状态管理
const useUserStore = defineStore(‘user’, {
state: () => ({
currentUser: null,
onlineUsers: []
}),
actions: {
setCurrentUser(user) {
this.currentUser = user;
localStorage.setItem(‘chatUser’, JSON.stringify(user));
},
clearCurrentUser() {
this.currentUser = null;
localStorage.removeItem(‘chatUser’);
},
updateOnlineUsers(users) {
this.onlineUsers = users;
},
addOnlineUser(user) {
if (!this.onlineUsers.find(u => u.id === user.id)) {
this.onlineUsers.push(user);
}
},
removeOnlineUser(userId) {
this.onlineUsers = this.onlineUsers.filter(user => user.id !== userId);
}
}
});

// 消息状态管理
const useMessageStore = defineStore(‘messages’, {
state: () => ({
messages: [],
isConnected: false,
socket: null
}),
actions: {
addMessage(message) {
this.messages.push(message);
// 保持消息数量不超过200条
if (this.messages.length > 200) {
this.messages = this.messages.slice(-200);
}
},
setConnectionStatus(connected) {
this.isConnected = connected;
},
initializeWebSocket() {
// 模拟WebSocket连接,实际项目中替换为真实的WebSocket连接
this.setConnectionStatus(true);

// 模拟接收消息
setInterval(() => {
if (this.isConnected && Math.random() > 0.7) {
const users = useUserStore().onlineUsers;
const randomUser = users[Math.floor(Math.random() * users.length)];
if (randomUser) {
this.addMessage({
id: Date.now() + Math.random(),
userId: randomUser.id,
username: randomUser.username,
avatarColor: randomUser.avatarColor,
text: this.generateRandomMessage(),
timestamp: Date.now()
});
}
}
}, 5000);
},
generateRandomMessage() {
const messages = [
‘大家好!今天天气真不错’,
‘有人在线吗?’,
‘Vue3真是太棒了!’,
‘这个聊天室是用Vue3构建的’,
Composition API让代码组织更清晰’,
Pinia状态管理很好用’,
‘WebSocket实现实时通信’,
‘前端开发很有趣’
];
return messages[Math.floor(Math.random() * messages.length)];
},
sendMessage(text, user) {
const message = {
id: Date.now(),
userId: user.id,
username: user.username,
avatarColor: user.avatarColor,
text: text,
timestamp: Date.now()
};
this.addMessage(message);

// 模拟消息发送到服务器
console.log(‘消息已发送:’, message);
},
disconnect() {
this.setConnectionStatus(false);
if (this.socket) {
this.socket.close();
this.socket = null;
}
}
}
});

const app = createApp({
setup() {
const userStore = useUserStore();
const messageStore = useMessageStore();

const loginForm = reactive({
username: ”,
avatarColor: ‘#4CAF50’
});

const newMessage = ref(”);
const messagesContainer = ref(null);

// 自动滚动到最新消息
const scrollToBottom = async () => {
await nextTick();
if (messagesContainer.value) {
messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight;
}
};

// 监听消息变化,自动滚动
watch(() => messageStore.messages.length, scrollToBottom);

const login = () => {
const user = {
id: Date.now().toString(),
username: loginForm.username,
avatarColor: loginForm.avatarColor
};
userStore.setCurrentUser(user);
userStore.addOnlineUser(user);

// 初始化WebSocket连接
messageStore.initializeWebSocket();
};

const logout = () => {
userStore.clearCurrentUser();
messageStore.disconnect();
};

const sendMessage = () => {
if (newMessage.value.trim() && userStore.currentUser) {
messageStore.sendMessage(newMessage.value.trim(), userStore.currentUser);
newMessage.value = ”;
}
};

const formatTime = (timestamp) => {
return new Date(timestamp).toLocaleTimeString(‘zh-CN’, {
hour: ‘2-digit’,
minute: ‘2-digit’
});
};

// 初始化:检查本地存储的用户信息
onMounted(() => {
const savedUser = localStorage.getItem(‘chatUser’);
if (savedUser) {
const user = JSON.parse(savedUser);
userStore.setCurrentUser(user);
userStore.addOnlineUser(user);
messageStore.initializeWebSocket();
}
});

// 组件卸载时断开连接
onUnmounted(() => {
messageStore.disconnect();
});

return {
currentUser: computed(() => userStore.currentUser),
onlineUsers: computed(() => userStore.onlineUsers),
messages: computed(() => messageStore.messages),
isConnected: computed(() => messageStore.isConnected),
loginForm,
newMessage,
messagesContainer,
login,
logout,
sendMessage,
formatTime
};
}
});

app.use(pinia);
app.mount(‘#app’);

Vue3实战:构建现代化实时聊天应用 | Composition API与WebSocket深度应用
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

淘吗网 vue3 Vue3实战:构建现代化实时聊天应用 | Composition API与WebSocket深度应用 https://www.taomawang.com/web/vue3/944.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务