slogan3

Ontwikkel een Vue.js Component met Geavanceerde State Synchronisatie via Composables

description

Met deze prompt leer je hoe je state efficiënt synchroniseert tussen Vue.js componenten met composables. Dit verbetert de code onderhoudbaarheid en performance, en voorkomt complexe stateproblemen. Het biedt een moderne aanpak die beter schaalbaar is dan traditionele methoden.

prompt

Help me een Vue.js component te ontwikkelen dat geavanceerde state synchronisatie gebruikt via Vue 3 composables. Beschrijf hoe ik gedeelde state kan beheren, updates tussen componenten kan synchroniseren en performance kan optimaliseren met ...

try_prompt

generate_helper
disclaimerOnPageApi

ai_answers

provider: openai
model: gpt-4.1-nano
Hier is een stapsgewijze gids om een Vue 3 component te ontwikkelen die geavanceerde state-synchronisatie gebruikt via composables, gericht op een realtime berichteninterface met gedeelde state, gesynchroniseerde updates en optimale performance: ### 1. Gedeelde state beheren met een composable Gebruik een Vue 3 composable (bijvoorbeeld `useChatState`) om de gedeelde state centraal te beheren: ```js // useChatState.js import { reactive } from 'vue'; export function useChatState() { const state = reactive({ berichten: [], // lijst van berichten onlineGebruikers: [] // lijst van online gebruikers }); // Methoden om state te muteren (bijvoorbeeld berichten toevoegen) function voegBerichtToe(bericht) { state.berichten.push(bericht); } function updateOnlineGebruikers(users) { state.onlineGebruikers = users; } return { state, voegBerichtToe, updateOnlineGebruikers }; } ``` ### 2. Realtime synchronisatie via WebSocket of een vergelijkbare service Gebruik een WebSocket-verbinding om de state te synchroniseren zonder vertraging: ```js // useWebSocket.js import { ref, onMounted, onUnmounted } from 'vue'; export function useWebSocket(url, onMessageCallback) { const socket = ref(null); onMounted(() => { socket.value = new WebSocket(url); socket.value.onmessage = (event) => { const data = JSON.parse(event.data); onMessageCallback(data); }; }); onUnmounted(() => { if (socket.value) { socket.value.close(); } }); function send(data) { if (socket.value && socket.value.readyState === WebSocket.OPEN) { socket.value.send(JSON.stringify(data)); } } return { send, socket: socket.value }; } ``` ### 3. Component integratie Gebruik de composables in je component: ```vue <template> <div> <h2>Realtime Chat</h2> <div class="berichten"> <div v-for="(bericht, index) in chatState.state.berichten" :key="index"> {{ bericht.gebruiker }}: {{ bericht.text }} </div> </div> <input v-model="nieuwBericht" @keyup.enter="verzendBericht" placeholder="Typ een bericht..." /> <div> <h3>Online gebruikers:</h3> <ul> <li v-for="user in chatState.state.onlineGebruikers" :key="user.id">{{ user.name }}</li> </ul> </div> </div> </template> <script> import { ref } from 'vue'; import { useChatState } from './useChatState'; import { useWebSocket } from './useWebSocket'; export default { setup() { const chatState = useChatState(); const nieuwBericht = ref(''); const { send } = useWebSocket('wss://jouw-websocket-url', (data) => { if (data.type === 'bericht') { chatState.voegBerichtToe(data.bericht); } else if (data.type === 'onlineUsers') { chatState.updateOnlineGebruikers(data.gebruikers); } }); function verzendBericht() { const bericht = { gebruiker: 'Huidige Gebruiker', // vervang door dynamische naam text: nieuwBericht.value, timestamp: Date.now() }; chatState.voegBerichtToe(bericht); send({ type: 'bericht', bericht }); nieuwBericht.value = ''; } return { chatState, nieuwBericht, verzendBericht }; } }; </script> ``` ### 4. Performance optimalisaties - **Vermijd onnodige re-renders:** Maak gebruik van `shallowReactive` of `shallowRef` indien nodig, om alleen de benodigde delen te reactiveren. - **Batch updates:** Verzamel snelle opeenvolgende berichten en verzend ze in één batch, bijvoorbeeld met debounce. - **Gebruik WebSocket-verbindingen efficiënt:** Houd de verbinding open en minimaliseer herhaald opzetten. - **Vue's `watch` of `computed`:** Gebruik deze voor geoptimaliseerde reactieve berekeningen en om updates te beperken. ### Samenvatting - Centraliseer gedeelde state in een composable. - Gebruik WebSockets voor realtime communicatie, met een composable voor de connectie. - Synchroniseer berichten en gebruikersstatus direct via WebSocket-berichten. - Optimaliseer prestaties door het beperken van onnodige re-renders, batching en efficiënte WebSocket-gebruik. Door deze aanpak krijg je een schaalbare, reactieve en performante Vue.js realtime chatinterface!
provider: deepseek
model: deepseek-chat
Ik zal je helpen een Vue.js 3 component te ontwikkelen met geavanceerde state synchronisatie via composables. Hier is een complete implementatie: ## 1. State Management Composable ```javascript // composables/useChatState.js import { ref, computed, watch, readonly } from 'vue' import { useWebSocket } from './useWebSocket' export function useChatState() { const messages = ref([]) const onlineUsers = ref(new Set()) const currentUser = ref(null) const isLoading = ref(false) // WebSocket integratie voor realtime updates const { connect, sendMessage, isConnected } = useWebSocket() // Gecacheerde computed properties voor performance const sortedMessages = computed(() => { return [...messages.value].sort((a, b) => new Date(a.timestamp) - new Date(b.timestamp) ) }) const onlineUsersList = computed(() => { return Array.from(onlineUsers.value) }) // State synchronisatie functies const addMessage = (message) => { messages.value.push({ ...message, id: Date.now() + Math.random(), timestamp: new Date().toISOString() }) // Optimalisatie: behoud alleen laatste 100 berichten if (messages.value.length > 100) { messages.value = messages.value.slice(-100) } } const updateOnlineUsers = (users) => { onlineUsers.value = new Set(users) } const setCurrentUser = (user) => { currentUser.value = user } // Real-time synchronisatie via WebSocket const initializeChat = async (user) => { isLoading.value = true setCurrentUser(user) try { await connect('wss://your-websocket-server/chat') // Luister naar realtime updates watch(isConnected, (connected) => { if (connected) { // Synchroniseer initiële state sendMessage({ type: 'join', user: user }) } }) } catch (error) { console.error('Chat initialisatie mislukt:', error) } finally { isLoading.value = false } } // Exporteer alleen wat nodig is (encapsulatie) return { messages: readonly(messages), sortedMessages: readonly(sortedMessages), onlineUsers: readonly(onlineUsers), onlineUsersList: readonly(onlineUsersList), currentUser: readonly(currentUser), isLoading: readonly(isLoading), addMessage, updateOnlineUsers, setCurrentUser, initializeChat } } ``` ## 2. WebSocket Composable voor Realtime Synchronisatie ```javascript // composables/useWebSocket.js import { ref, onUnmounted } from 'vue' export function useWebSocket() { const socket = ref(null) const isConnected = ref(false) const reconnectAttempts = ref(0) const maxReconnectAttempts = 5 const messageHandlers = new Set() const connect = (url) => { return new Promise((resolve, reject) => { try { socket.value = new WebSocket(url) socket.value.onopen = () => { isConnected.value = true reconnectAttempts.value = 0 resolve() } socket.value.onmessage = (event) => { const data = JSON.parse(event.data) messageHandlers.forEach(handler => handler(data)) } socket.value.onclose = () => { isConnected.value = false attemptReconnect() } socket.value.onerror = (error) => { reject(error) } } catch (error) { reject(error) } }) } const attemptReconnect = () => { if (reconnectAttempts.value < maxReconnectAttempts) { setTimeout(() => { reconnectAttempts.value++ connect(socket.value.url) }, 1000 * reconnectAttempts.value) } } const sendMessage = (message) => { if (socket.value && isConnected.value) { socket.value.send(JSON.stringify(message)) } } const onMessage = (handler) => { messageHandlers.add(handler) // Cleanup functie retourneren return () => messageHandlers.delete(handler) } onUnmounted(() => { if (socket.value) { socket.value.close() } }) return { connect, sendMessage, onMessage, isConnected: readonly(isConnected) } } ``` ## 3. Hoofd Chat Component ```vue <!-- components/ChatInterface.vue --> <template> <div class="chat-interface"> <!-- Loading state --> <div v-if="isLoading" class="loading"> Chat initialiseren... </div> <!-- Hoofd chat interface --> <div v-else class="chat-container"> <!-- Online gebruikers sidebar --> <div class="online-users"> <h3>Online Gebruikers ({{ onlineUsersList.length }})</h3> <div v-for="user in onlineUsersList" :key="user.id" class="user-item" :class="{ active: user.id === currentUser?.id }" > {{ user.name }} </div> </div> <!-- Chat berichten gebied --> <div class="chat-messages"> <div class="messages-container"> <div v-for="message in sortedMessages" :key="message.id" class="message" :class="{ own: message.userId === currentUser?.id }" > <div class="message-header"> <strong>{{ message.userName }}</strong> <span class="timestamp"> {{ formatTime(message.timestamp) }} </span> </div> <div class="message-content">{{ message.content }}</div> </div> </div> <!-- Bericht invoer --> <div class="message-input"> <input v-model="newMessage" @keyup.enter="sendMessage" placeholder="Typ je bericht..." :disabled="!isConnected" /> <button @click="sendMessage" :disabled="!newMessage.trim() || !isConnected" > Verstuur </button> </div> </div> </div> </div> </template> <script setup> import { ref, onMounted, onUnmounted } from 'vue' import { useChatState } from '@/composables/useChatState' // State management via composable const { sortedMessages, onlineUsersList, currentUser, isLoading, isConnected, addMessage, updateOnlineUsers, initializeChat } = useChatState() const newMessage = ref('') // Component lifecycle onMounted(() => { // Initialiseer chat met huidige gebruiker initializeChat({ id: 'user-123', name: 'Jouw Naam' }) }) // Bericht verzenden const sendMessage = () => { if (!newMessage.value.trim()) return addMessage({ content: newMessage.value.trim(), userId: currentUser.value.id, userName: currentUser.value.name }) newMessage.value = '' } // Tijd formatting helper const formatTime = (timestamp) => { return new Date(timestamp).toLocaleTimeString('nl-NL', { hour: '2-digit', minute: '2-digit' }) } </script> <style scoped> .chat-interface { height: 100vh; display: flex; } .chat-container { display: flex; width: 100%; height: 100%; } .online-users { width: 250px; border-right: 1px solid #ddd; padding: 1rem; } .chat-messages { flex: 1; display: flex; flex-direction: column; } .messages-container { flex: 1; overflow-y: auto; padding: 1rem; } .message { margin-bottom: 1rem; padding: 0.5rem; border-radius: 8px; } .message.own { background-color: #e3f2fd; margin-left: 2rem; } .message-input { padding: 1rem; border-top: 1px solid #ddd; display: flex; gap: 0.5rem; } .message-input input { flex: 1; padding: 0.5rem; } </style> ``` ## 4. Gebruik in Je Applicatie ```javascript // App.vue <script setup> import ChatInterface from '@/components/ChatInterface.vue' </script> <template> <div id="app"> <ChatInterface /> </div> </template> ``` ## Belangrijke Performance Optimalisaties: 1. **Readonly State**: Gebruik `readonly()` om per ongeluk mutaties te voorkomen 2. **Efficiente Updates**: Batched updates via WebSocket messages 3. **Memory Management**: Beperk berichtengeschiedenis tot 100 items 4. **Computed Caching**: `sortedMessages` en `onlineUsersList` zijn gecached 5. **Connection Management**: Automatische reconnect met exponential backoff 6. **Event Handling**: Efficient message handling via Set collection Deze architectuur zorgt voor naadloze realtime synchronisatie tussen componenten met optimale performance!
error: Generation failed [deepseek] prompt_id=4095 locale=en err=DeepSeek connection/timeout | Generation failed [deepseek] prompt_id=4095 locale=pt err=DeepSeek connection/timeout