登录聊天室
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’);