@elsahafy/ux-mcp-server 2.0.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +159 -18
- package/dist/index.js +2130 -8
- package/knowledge/ai-ml-patterns.json +192 -0
- package/knowledge/analytics-metrics.json +521 -0
- package/knowledge/angular-patterns.json +347 -0
- package/knowledge/ar-vr-interfaces.json +139 -0
- package/knowledge/color-theory.json +499 -0
- package/knowledge/data-viz.json +527 -0
- package/knowledge/design-system-advanced.json +533 -0
- package/knowledge/ecommerce-patterns.json +616 -0
- package/knowledge/ethical-design.json +484 -0
- package/knowledge/finance-ux.json +208 -0
- package/knowledge/forms.json +641 -0
- package/knowledge/haptic-feedback.json +102 -0
- package/knowledge/healthcare-ux.json +209 -0
- package/knowledge/information-architecture.json +494 -0
- package/knowledge/microcopy.json +743 -0
- package/knowledge/mobile-patterns.json +537 -0
- package/knowledge/neurodiversity.json +228 -0
- package/knowledge/pwa-patterns.json +429 -0
- package/knowledge/saas-patterns.json +613 -0
- package/knowledge/testing-validation.json +561 -0
- package/knowledge/typography.json +509 -0
- package/knowledge/voice-ui.json +359 -0
- package/knowledge/vue-patterns.json +279 -0
- package/knowledge/web-components.json +148 -0
- package/package.json +1 -1
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Voice User Interface (VUI) Design",
|
|
3
|
+
"description": "Comprehensive guide to designing voice user interfaces for voice assistants, smart speakers, and voice-enabled applications",
|
|
4
|
+
"definition": "Voice User Interface (VUI) is a speech-based interaction system that allows users to interact with technology through voice commands and spoken language.",
|
|
5
|
+
"platforms": {
|
|
6
|
+
"smart_speakers": ["Amazon Alexa", "Google Assistant", "Apple Siri", "Samsung Bixby"],
|
|
7
|
+
"voice_assistants": ["Siri (iOS)", "Google Assistant (Android)", "Cortana (Windows)"],
|
|
8
|
+
"voice_apps": ["Voice skills (Alexa)", "Actions (Google)", "Shortcuts (Siri)"],
|
|
9
|
+
"automotive": ["CarPlay", "Android Auto", "In-vehicle assistants"],
|
|
10
|
+
"accessibility": "Voice interfaces for users with disabilities (blind, motor impairments)"
|
|
11
|
+
},
|
|
12
|
+
"vui_principles": {
|
|
13
|
+
"conversational": {
|
|
14
|
+
"description": "Sound natural, like human conversation",
|
|
15
|
+
"practices": [
|
|
16
|
+
"Use contractions (don't, can't, won't)",
|
|
17
|
+
"Vary responses (avoid robotic repetition)",
|
|
18
|
+
"Match user's language level",
|
|
19
|
+
"Be concise (spoken word is slower than reading)",
|
|
20
|
+
"Use pronouns to avoid repetition"
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
"cooperative": {
|
|
24
|
+
"description": "Be helpful and collaborative",
|
|
25
|
+
"practices": [
|
|
26
|
+
"Provide help when user is stuck",
|
|
27
|
+
"Confirm important actions",
|
|
28
|
+
"Offer alternatives when request can't be fulfilled",
|
|
29
|
+
"Guide user toward successful completion"
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
"succinct": {
|
|
33
|
+
"description": "Respect user's time and attention",
|
|
34
|
+
"practices": [
|
|
35
|
+
"Lead with most important information",
|
|
36
|
+
"Limit to 1-2 sentences per response",
|
|
37
|
+
"Avoid unnecessary pleasantries after first interaction",
|
|
38
|
+
"Use progressive disclosure (don't list everything at once)"
|
|
39
|
+
]
|
|
40
|
+
},
|
|
41
|
+
"clear": {
|
|
42
|
+
"description": "Unambiguous and easy to understand",
|
|
43
|
+
"practices": [
|
|
44
|
+
"Avoid jargon and technical terms",
|
|
45
|
+
"Use simple sentence structure",
|
|
46
|
+
"Pronounce numbers and acronyms clearly",
|
|
47
|
+
"Provide context for choices"
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"conversation_design": {
|
|
52
|
+
"dialog_structure": {
|
|
53
|
+
"greeting": {
|
|
54
|
+
"first_time": "Welcome! I'm [Name]. I can help you [primary functions]. What would you like to do?",
|
|
55
|
+
"returning": "Welcome back! What can I help with today?",
|
|
56
|
+
"best_practices": ["Brief (< 10 seconds)", "Set expectations", "Offer help", "Don't repeat full intro every time"]
|
|
57
|
+
},
|
|
58
|
+
"prompts": {
|
|
59
|
+
"open_ended": {
|
|
60
|
+
"use": "When options are many or unknown",
|
|
61
|
+
"example": "What would you like to order?",
|
|
62
|
+
"risk": "User may not know what to say"
|
|
63
|
+
},
|
|
64
|
+
"closed_ended": {
|
|
65
|
+
"use": "When options are limited",
|
|
66
|
+
"example": "Would you like pickup or delivery?",
|
|
67
|
+
"benefit": "Easier for user, clearer intent"
|
|
68
|
+
},
|
|
69
|
+
"directed": {
|
|
70
|
+
"use": "Guide user with examples",
|
|
71
|
+
"example": "You can say things like 'Order a pizza' or 'Check my order status'. What would you like?"
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
"confirmations": {
|
|
75
|
+
"implicit": "Used for low-stakes actions. Example: 'OK, setting your alarm for 7 AM.'",
|
|
76
|
+
"explicit": "Used for high-stakes actions. Example: 'I'll charge your card $50. Is that OK?'",
|
|
77
|
+
"best_practice": "Always confirm destructive or financial actions"
|
|
78
|
+
},
|
|
79
|
+
"error_handling": {
|
|
80
|
+
"no_match": {
|
|
81
|
+
"description": "System didn't understand",
|
|
82
|
+
"response": "Sorry, I didn't catch that. Could you repeat?",
|
|
83
|
+
"after_2nd_failure": "I'm having trouble understanding. You can say [examples], or say 'help'.",
|
|
84
|
+
"after_3rd_failure": "Let me connect you to a person who can help."
|
|
85
|
+
},
|
|
86
|
+
"no_input": {
|
|
87
|
+
"description": "User didn't respond",
|
|
88
|
+
"response": "Are you still there?",
|
|
89
|
+
"timeout": "OK, let me know if you need anything."
|
|
90
|
+
},
|
|
91
|
+
"out_of_scope": {
|
|
92
|
+
"description": "Request not supported",
|
|
93
|
+
"response": "I can't do that yet, but I can help you [supported actions]. What would you like?",
|
|
94
|
+
"avoid": "Just saying 'I can't do that' (dead end)"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
"persona": {
|
|
99
|
+
"description": "Voice assistant's personality",
|
|
100
|
+
"considerations": {
|
|
101
|
+
"tone": "Professional, friendly, casual, formal (match brand and audience)",
|
|
102
|
+
"vocabulary": "Match user's language level and domain",
|
|
103
|
+
"humor": "Use sparingly, avoid sarcasm (tone doesn't translate)",
|
|
104
|
+
"empathy": "Acknowledge user frustration or celebrate success"
|
|
105
|
+
},
|
|
106
|
+
"consistency": "Maintain persona across all interactions"
|
|
107
|
+
},
|
|
108
|
+
"sample_size": {
|
|
109
|
+
"description": "Variety of user utterances to account for",
|
|
110
|
+
"example": "User wants to order pizza - 'I want a pizza', 'Order pizza', 'Get me a large pepperoni', 'Pizza delivery'",
|
|
111
|
+
"recommendation": "Support 10-20 variations per intent",
|
|
112
|
+
"tools": "Natural Language Understanding (NLU) handles variations"
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
"voice_design_patterns": {
|
|
116
|
+
"one_shot": {
|
|
117
|
+
"description": "User completes task in single utterance",
|
|
118
|
+
"example": "'Alexa, set timer for 10 minutes'",
|
|
119
|
+
"use_when": "Simple, frequent tasks",
|
|
120
|
+
"benefit": "Fastest interaction"
|
|
121
|
+
},
|
|
122
|
+
"multi_turn": {
|
|
123
|
+
"description": "Back-and-forth dialog to complete task",
|
|
124
|
+
"example": "User: 'Book a flight'\nAssistant: 'Where to?'\nUser: 'New York'\nAssistant: 'What date?'\nUser: 'Next Friday'",
|
|
125
|
+
"use_when": "Complex tasks requiring multiple inputs",
|
|
126
|
+
"best_practices": ["Keep turns short", "Confirm at end", "Allow editing previous answers", "Show progress"]
|
|
127
|
+
},
|
|
128
|
+
"disambiguation": {
|
|
129
|
+
"description": "Clarify ambiguous requests",
|
|
130
|
+
"example": "User: 'Play Hamilton'\nAssistant: 'I found the musical soundtrack and the audiobook. Which would you like?'",
|
|
131
|
+
"best_practice": "Limit choices to 2-3, provide clear distinctions"
|
|
132
|
+
},
|
|
133
|
+
"slot_filling": {
|
|
134
|
+
"description": "Collect required information progressively",
|
|
135
|
+
"example": "Booking flight - collect: destination, date, passengers, class",
|
|
136
|
+
"best_practice": "Ask for required slots first, optional later"
|
|
137
|
+
},
|
|
138
|
+
"context_carryover": {
|
|
139
|
+
"description": "Remember previous context in conversation",
|
|
140
|
+
"example": "User: 'Weather in Seattle'\nAssistant: '65 and sunny'\nUser: 'How about tomorrow?'\nAssistant (remembers Seattle): 'Tomorrow in Seattle will be 62 and cloudy'",
|
|
141
|
+
"use_when": "Follow-up questions, refinements"
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
"accessibility": {
|
|
145
|
+
"for_blind_users": {
|
|
146
|
+
"importance": "Voice UI is primary interface for blind users",
|
|
147
|
+
"best_practices": [
|
|
148
|
+
"Provide audio feedback for all actions",
|
|
149
|
+
"Describe visual content (images, charts)",
|
|
150
|
+
"Support navigation without visual cues",
|
|
151
|
+
"Avoid relying on screen for critical info"
|
|
152
|
+
]
|
|
153
|
+
},
|
|
154
|
+
"for_motor_impairments": {
|
|
155
|
+
"importance": "Voice eliminates need for physical interaction",
|
|
156
|
+
"best_practices": [
|
|
157
|
+
"Support full functionality via voice",
|
|
158
|
+
"Avoid requiring rapid responses",
|
|
159
|
+
"Allow pauses without timeout"
|
|
160
|
+
]
|
|
161
|
+
},
|
|
162
|
+
"for_cognitive_disabilities": {
|
|
163
|
+
"best_practices": [
|
|
164
|
+
"Use simple language",
|
|
165
|
+
"Keep responses short",
|
|
166
|
+
"Provide help easily ('say help')",
|
|
167
|
+
"Be patient with errors"
|
|
168
|
+
]
|
|
169
|
+
},
|
|
170
|
+
"accent_diversity": {
|
|
171
|
+
"challenge": "Voice recognition may struggle with accents",
|
|
172
|
+
"mitigation": [
|
|
173
|
+
"Train models on diverse accents",
|
|
174
|
+
"Provide text fallback option",
|
|
175
|
+
"Allow spelling out words"
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
"multimodal": {
|
|
180
|
+
"description": "Combining voice with visual display",
|
|
181
|
+
"devices": ["Smart displays (Echo Show, Nest Hub)", "Smartphones", "Car displays"],
|
|
182
|
+
"benefits": [
|
|
183
|
+
"Visual confirmation of voice commands",
|
|
184
|
+
"Show complex information (lists, images)",
|
|
185
|
+
"Fallback for misheard commands",
|
|
186
|
+
"Enhanced accessibility"
|
|
187
|
+
],
|
|
188
|
+
"best_practices": {
|
|
189
|
+
"design_for_voice_first": "Voice should work standalone (visual is enhancement)",
|
|
190
|
+
"sync_visual_audio": "Visual should match what's being said",
|
|
191
|
+
"brevity_visual": "Don't show walls of text (people will ask to scroll)",
|
|
192
|
+
"touch_optional": "Allow touch but don't require it"
|
|
193
|
+
},
|
|
194
|
+
"patterns": {
|
|
195
|
+
"list_navigation": "Voice reads items, visual shows list, user can scroll or say number",
|
|
196
|
+
"visual_confirmation": "Voice says action, visual shows result",
|
|
197
|
+
"complex_data": "Voice summarizes, visual shows detail (e.g., weather forecast)"
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
"testing": {
|
|
201
|
+
"script_testing": {
|
|
202
|
+
"description": "Test dialog flows with scripts",
|
|
203
|
+
"process": "Write out conversations, walk through all paths",
|
|
204
|
+
"check": ["Natural flow", "Error handling", "Edge cases", "Dead ends"]
|
|
205
|
+
},
|
|
206
|
+
"wizard_of_oz": {
|
|
207
|
+
"description": "Human plays role of voice assistant",
|
|
208
|
+
"process": "Users speak to 'assistant', human responds (simulates AI)",
|
|
209
|
+
"benefit": "Test before building, understand user language",
|
|
210
|
+
"use_when": "Early concept validation"
|
|
211
|
+
},
|
|
212
|
+
"user_testing": {
|
|
213
|
+
"description": "Test with real users and voice recognition",
|
|
214
|
+
"participants": "8-10 users representing target audience",
|
|
215
|
+
"environment": "Quiet room (minimize background noise)",
|
|
216
|
+
"observe": ["What users say", "Misrecognitions", "Confusion points", "Success rate"],
|
|
217
|
+
"metrics": ["Task completion rate", "Error rate", "Time to complete", "User satisfaction"]
|
|
218
|
+
},
|
|
219
|
+
"real_world_testing": {
|
|
220
|
+
"description": "Test in actual usage environments",
|
|
221
|
+
"scenarios": ["Noisy kitchen (cooking)", "Moving vehicle", "Background TV/music"],
|
|
222
|
+
"challenge": "Far-field voice recognition, background noise"
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
"technical_considerations": {
|
|
226
|
+
"voice_recognition": {
|
|
227
|
+
"accuracy": "Aim for > 95% word error rate",
|
|
228
|
+
"challenges": ["Accents", "Background noise", "Homophones (two, too, to)"],
|
|
229
|
+
"mitigation": "Train models on diverse speech, use context to disambiguate"
|
|
230
|
+
},
|
|
231
|
+
"natural_language_understanding": {
|
|
232
|
+
"nlu": "Understand user intent from varied utterances",
|
|
233
|
+
"entities": "Extract specific info (dates, locations, names)",
|
|
234
|
+
"intents": "User's goal (OrderPizza, CheckWeather, SetAlarm)",
|
|
235
|
+
"example": "'Book flight to NYC on Friday' → Intent: BookFlight, Entities: {destination: NYC, date: Friday}"
|
|
236
|
+
},
|
|
237
|
+
"text_to_speech": {
|
|
238
|
+
"tts": "Convert text responses to spoken audio",
|
|
239
|
+
"quality": "Use neural TTS for natural-sounding voices",
|
|
240
|
+
"customization": ["Adjust speed", "Emphasis with SSML", "Pauses"],
|
|
241
|
+
"ssml": "Speech Synthesis Markup Language for control (pitch, rate, volume, pauses)"
|
|
242
|
+
},
|
|
243
|
+
"wake_words": {
|
|
244
|
+
"description": "Activation phrase (Alexa, Hey Google, Hey Siri)",
|
|
245
|
+
"challenge": "Always listening raises privacy concerns",
|
|
246
|
+
"best_practice": "Clear indicator when listening (light, chime)",
|
|
247
|
+
"privacy": "Local wake word detection, cloud for processing"
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
"privacy_ethics": {
|
|
251
|
+
"always_listening": {
|
|
252
|
+
"concern": "Device always listening for wake word",
|
|
253
|
+
"mitigation": ["Visual indicator when active", "Mute button", "Delete history option"],
|
|
254
|
+
"transparency": "Explain data collection and usage"
|
|
255
|
+
},
|
|
256
|
+
"data_retention": {
|
|
257
|
+
"concern": "Voice recordings stored",
|
|
258
|
+
"best_practice": ["Allow users to delete history", "Auto-delete after X days option", "Don't require login for basic features"],
|
|
259
|
+
"legal": "GDPR requires data deletion and export"
|
|
260
|
+
},
|
|
261
|
+
"consent": {
|
|
262
|
+
"requirement": "Explain voice data usage before collection",
|
|
263
|
+
"best_practice": "Opt-in, not opt-out"
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
"best_practices": [
|
|
267
|
+
"Design for voice-first (visual is enhancement)",
|
|
268
|
+
"Be conversational (use contractions, vary responses)",
|
|
269
|
+
"Keep responses short (< 10 seconds, 1-2 sentences)",
|
|
270
|
+
"Confirm high-stakes actions explicitly",
|
|
271
|
+
"Provide help when user is stuck",
|
|
272
|
+
"Support varied phrasings (10-20 per intent)",
|
|
273
|
+
"Handle errors gracefully (reprompt, offer examples, escalate)",
|
|
274
|
+
"Test with diverse accents and backgrounds",
|
|
275
|
+
"Use simple language (avoid jargon)",
|
|
276
|
+
"Provide clear visual feedback in multimodal",
|
|
277
|
+
"Respect user privacy (clear indicators, delete options)",
|
|
278
|
+
"Design for accessibility (voice is critical for blind users)",
|
|
279
|
+
"Avoid dead ends (always offer next step)",
|
|
280
|
+
"Context carryover for follow-ups",
|
|
281
|
+
"Progressive disclosure (don't list all options)"
|
|
282
|
+
],
|
|
283
|
+
"anti_patterns": [
|
|
284
|
+
"Robotic, unnatural language",
|
|
285
|
+
"Long, verbose responses (> 30 seconds)",
|
|
286
|
+
"No error handling (just fails)",
|
|
287
|
+
"Requiring exact phrasing",
|
|
288
|
+
"No confirmation for destructive actions",
|
|
289
|
+
"Dead ends ('I can't do that' with no alternative)",
|
|
290
|
+
"Repeating full greeting every time",
|
|
291
|
+
"Relying on screen for critical info (voice-first!)",
|
|
292
|
+
"Not testing with real users",
|
|
293
|
+
"Ignoring accents and speech variations",
|
|
294
|
+
"No visual feedback in multimodal interfaces",
|
|
295
|
+
"Always-on with no privacy controls",
|
|
296
|
+
"Complex menu navigation (press 1 for...)",
|
|
297
|
+
"Not handling noise/background audio",
|
|
298
|
+
"Forgetting context (user must repeat info)"
|
|
299
|
+
],
|
|
300
|
+
"metrics": {
|
|
301
|
+
"task_success_rate": "% of users who complete task successfully",
|
|
302
|
+
"error_rate": "% of utterances not understood",
|
|
303
|
+
"average_turns": "Number of back-and-forth exchanges (fewer is better for simple tasks)",
|
|
304
|
+
"time_to_completion": "How long task takes",
|
|
305
|
+
"user_satisfaction": "Post-task survey (SUS, CSAT)",
|
|
306
|
+
"retention": "Do users return?",
|
|
307
|
+
"wake_word_accuracy": "% of wake word detections that are true positives"
|
|
308
|
+
},
|
|
309
|
+
"tools_frameworks": {
|
|
310
|
+
"amazon_alexa": {
|
|
311
|
+
"platform": "Amazon Echo, Fire TV",
|
|
312
|
+
"development": "Alexa Skills Kit (ASK)",
|
|
313
|
+
"language": "Node.js, Python, Java",
|
|
314
|
+
"strength": "Largest skill library, smart home integration"
|
|
315
|
+
},
|
|
316
|
+
"google_assistant": {
|
|
317
|
+
"platform": "Google Home, Android, iOS",
|
|
318
|
+
"development": "Actions on Google, Dialogflow",
|
|
319
|
+
"language": "Node.js, Java, Python",
|
|
320
|
+
"strength": "Best voice recognition, Google services integration"
|
|
321
|
+
},
|
|
322
|
+
"apple_siri": {
|
|
323
|
+
"platform": "iOS, macOS, HomePod",
|
|
324
|
+
"development": "SiriKit, Shortcuts",
|
|
325
|
+
"limitation": "More restrictive, limited domains",
|
|
326
|
+
"strength": "Apple ecosystem integration"
|
|
327
|
+
},
|
|
328
|
+
"web_speech_api": {
|
|
329
|
+
"description": "Browser-based voice recognition and synthesis",
|
|
330
|
+
"use": "Voice interfaces in web apps",
|
|
331
|
+
"support": "Chrome, Edge, Safari (partial)"
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
"case_studies": {
|
|
335
|
+
"dominos_pizza": {
|
|
336
|
+
"approach": "Voice ordering via Alexa and Google",
|
|
337
|
+
"feature": "'Easy Order' - one phrase to order favorite",
|
|
338
|
+
"result": "Increased orders, improved accessibility"
|
|
339
|
+
},
|
|
340
|
+
"capital_one": {
|
|
341
|
+
"approach": "Banking via Alexa (balance, payments, transactions)",
|
|
342
|
+
"security": "Voice PIN for authentication",
|
|
343
|
+
"result": "Convenient banking for customers"
|
|
344
|
+
},
|
|
345
|
+
"mayo_clinic": {
|
|
346
|
+
"approach": "Symptom checker and health info via voice",
|
|
347
|
+
"benefit": "Accessible health information",
|
|
348
|
+
"use_case": "Hands-free (cooking, driving)"
|
|
349
|
+
}
|
|
350
|
+
},
|
|
351
|
+
"resources": [
|
|
352
|
+
"Designing Voice User Interfaces (Cathy Pearl) - VUI design bible",
|
|
353
|
+
"Voice User Interface Design (Michael McTear et al.) - Academic perspective",
|
|
354
|
+
"Alexa Design Guide - Amazon's official VUI guidelines",
|
|
355
|
+
"Google Assistant Conversation Design - Google's guidelines",
|
|
356
|
+
"VUI Magazine - Voice UI publication",
|
|
357
|
+
"Project EVIA (Embodied Voice Industry Association)"
|
|
358
|
+
]
|
|
359
|
+
}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Vue.js Patterns & Best Practices",
|
|
3
|
+
"description": "Comprehensive guide to Vue.js component patterns, Composition API, state management, and performance optimization",
|
|
4
|
+
"version_note": "Patterns focus on Vue 3 with Composition API, with notes for Options API where relevant",
|
|
5
|
+
"composition_api": {
|
|
6
|
+
"description": "Modern Vue 3 API for organizing component logic",
|
|
7
|
+
"setup_function": {
|
|
8
|
+
"description": "Entry point for Composition API",
|
|
9
|
+
"example": "<script setup>\nimport { ref, computed, onMounted } from 'vue'\n\nconst count = ref(0)\nconst doubleCount = computed(() => count.value * 2)\n\nfunction increment() {\n count.value++\n}\n\nonMounted(() => {\n console.log('Component mounted')\n})\n</script>",
|
|
10
|
+
"benefits": ["Better TypeScript support", "Code organization by feature", "Easier reuse"]
|
|
11
|
+
},
|
|
12
|
+
"reactivity": {
|
|
13
|
+
"ref": {
|
|
14
|
+
"use": "Reactive primitive values",
|
|
15
|
+
"example": "const count = ref(0)\nconsole.log(count.value) // access with .value",
|
|
16
|
+
"when": "Numbers, strings, booleans"
|
|
17
|
+
},
|
|
18
|
+
"reactive": {
|
|
19
|
+
"use": "Reactive objects",
|
|
20
|
+
"example": "const state = reactive({ count: 0, name: 'John' })\nconsole.log(state.count) // no .value needed",
|
|
21
|
+
"when": "Objects with multiple properties"
|
|
22
|
+
},
|
|
23
|
+
"readonly": {
|
|
24
|
+
"use": "Immutable reactive state",
|
|
25
|
+
"example": "const state = reactive({ count: 0 })\nconst readonlyState = readonly(state)",
|
|
26
|
+
"when": "Prevent mutations from child components"
|
|
27
|
+
},
|
|
28
|
+
"toRefs": {
|
|
29
|
+
"use": "Convert reactive object to refs for destructuring",
|
|
30
|
+
"example": "const state = reactive({ count: 0, name: 'John' })\nconst { count, name } = toRefs(state)",
|
|
31
|
+
"benefit": "Preserve reactivity when destructuring"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"computed": {
|
|
35
|
+
"description": "Cached derived state",
|
|
36
|
+
"example": "const doubleCount = computed(() => count.value * 2)",
|
|
37
|
+
"benefits": ["Cached until dependencies change", "Read-only by default"],
|
|
38
|
+
"writable": "const fullName = computed({\n get: () => `${firstName.value} ${lastName.value}`,\n set: (value) => {\n const names = value.split(' ')\n firstName.value = names[0]\n lastName.value = names[1]\n }\n})"
|
|
39
|
+
},
|
|
40
|
+
"watchers": {
|
|
41
|
+
"watch": {
|
|
42
|
+
"description": "Watch single or multiple sources",
|
|
43
|
+
"example": "watch(count, (newVal, oldVal) => {\n console.log(`Count changed from ${oldVal} to ${newVal}`)\n})",
|
|
44
|
+
"multiple": "watch([foo, bar], ([newFoo, newBar], [oldFoo, oldBar]) => { ... })"
|
|
45
|
+
},
|
|
46
|
+
"watchEffect": {
|
|
47
|
+
"description": "Auto-tracks dependencies",
|
|
48
|
+
"example": "watchEffect(() => {\n console.log(`Count is ${count.value}`)\n})",
|
|
49
|
+
"when": "Don't need old value, automatic tracking"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"component_patterns": {
|
|
54
|
+
"composables": {
|
|
55
|
+
"description": "Reusable composition functions (like React hooks)",
|
|
56
|
+
"naming": "Prefix with 'use'",
|
|
57
|
+
"example": "// useCounter.js\nimport { ref, computed } from 'vue'\n\nexport function useCounter(initial = 0) {\n const count = ref(initial)\n const double = computed(() => count.value * 2)\n \n function increment() {\n count.value++\n }\n \n return { count, double, increment }\n}\n\n// In component:\nimport { useCounter } from './useCounter'\nconst { count, double, increment } = useCounter(10)",
|
|
58
|
+
"benefits": ["Logic reuse", "Code organization", "Testable"],
|
|
59
|
+
"best_practices": [
|
|
60
|
+
"Return reactive values and functions",
|
|
61
|
+
"Name with 'use' prefix",
|
|
62
|
+
"Keep focused (single responsibility)",
|
|
63
|
+
"Document parameters and return values"
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
"provide_inject": {
|
|
67
|
+
"description": "Dependency injection for component tree",
|
|
68
|
+
"provide": "const theme = ref('dark')\nprovide('theme', theme)",
|
|
69
|
+
"inject": "const theme = inject('theme')",
|
|
70
|
+
"use_when": "Pass data deep without props drilling",
|
|
71
|
+
"with_typescript": "// Provide typed injection key\nconst themeKey = Symbol() as InjectionKey<Ref<string>>\nprovide(themeKey, theme)\nconst theme = inject(themeKey)",
|
|
72
|
+
"default_values": "const theme = inject('theme', 'light')"
|
|
73
|
+
},
|
|
74
|
+
"slots": {
|
|
75
|
+
"default_slot": {
|
|
76
|
+
"parent": "<Card>\n <p>Default content</p>\n</Card>",
|
|
77
|
+
"component": "<template>\n <div class='card'>\n <slot />\n </div>\n</template>"
|
|
78
|
+
},
|
|
79
|
+
"named_slots": {
|
|
80
|
+
"parent": "<Card>\n <template #header>\n <h2>Title</h2>\n </template>\n <template #default>\n <p>Content</p>\n </template>\n <template #footer>\n <button>Action</button>\n </template>\n</Card>",
|
|
81
|
+
"component": "<template>\n <div class='card'>\n <header><slot name='header' /></header>\n <main><slot /></main>\n <footer><slot name='footer' /></footer>\n </div>\n</template>"
|
|
82
|
+
},
|
|
83
|
+
"scoped_slots": {
|
|
84
|
+
"description": "Pass data to slot content",
|
|
85
|
+
"parent": "<List :items='items'>\n <template #item='{ item, index }'>\n <div>{{ index }}: {{ item.name }}</div>\n </template>\n</List>",
|
|
86
|
+
"component": "<template>\n <div>\n <div v-for='(item, index) in items' :key='item.id'>\n <slot name='item' :item='item' :index='index' />\n </div>\n </div>\n</template>"
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"teleport": {
|
|
90
|
+
"description": "Render component content elsewhere in DOM",
|
|
91
|
+
"example": "<teleport to='body'>\n <Modal v-if='showModal'>\n <p>Modal content</p>\n </Modal>\n</teleport>",
|
|
92
|
+
"use_when": "Modals, toasts, tooltips that need to escape parent overflow"
|
|
93
|
+
},
|
|
94
|
+
"async_components": {
|
|
95
|
+
"description": "Lazy load components",
|
|
96
|
+
"example": "const AsyncComp = defineAsyncComponent(() =>\n import('./HeavyComponent.vue')\n)\n\n// With loading/error states:\nconst AsyncComp = defineAsyncComponent({\n loader: () => import('./HeavyComponent.vue'),\n loadingComponent: LoadingSpinner,\n errorComponent: ErrorDisplay,\n delay: 200,\n timeout: 3000\n})",
|
|
97
|
+
"use_when": "Large components, route-based code splitting"
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
"state_management": {
|
|
101
|
+
"local_state": {
|
|
102
|
+
"use_when": "Component-specific state",
|
|
103
|
+
"composition_api": "const count = ref(0)",
|
|
104
|
+
"options_api": "data() { return { count: 0 } }"
|
|
105
|
+
},
|
|
106
|
+
"props_state": {
|
|
107
|
+
"description": "Receive data from parent",
|
|
108
|
+
"composition_api": "const props = defineProps<{\n count: number\n name?: string\n}>()",
|
|
109
|
+
"with_defaults": "const props = withDefaults(defineProps<{\n count?: number\n}>(), {\n count: 0\n})",
|
|
110
|
+
"validation": "defineProps({\n count: {\n type: Number,\n required: true,\n validator: (value) => value >= 0\n }\n})"
|
|
111
|
+
},
|
|
112
|
+
"emits": {
|
|
113
|
+
"description": "Emit events to parent",
|
|
114
|
+
"composition_api": "const emit = defineEmits<{\n update: [value: number]\n delete: [id: string]\n}>()\n\nemit('update', 42)",
|
|
115
|
+
"v_model": "// Component\nconst emit = defineEmits(['update:modelValue'])\n\n// Parent\n<CustomInput v-model='text' />"
|
|
116
|
+
},
|
|
117
|
+
"pinia": {
|
|
118
|
+
"description": "Official state management for Vue 3",
|
|
119
|
+
"store_definition": "import { defineStore } from 'pinia'\n\nexport const useCounterStore = defineStore('counter', () => {\n const count = ref(0)\n const doubled = computed(() => count.value * 2)\n \n function increment() {\n count.value++\n }\n \n return { count, doubled, increment }\n})",
|
|
120
|
+
"usage": "import { useCounterStore } from '@/stores/counter'\n\nconst counter = useCounterStore()\ncounter.increment()\nconsole.log(counter.count)",
|
|
121
|
+
"features": ["DevTools support", "TypeScript", "Composition API style", "Lightweight"],
|
|
122
|
+
"when_to_use": "Global state, shared between routes/components"
|
|
123
|
+
},
|
|
124
|
+
"vuex": {
|
|
125
|
+
"description": "Legacy state management (Vue 2)",
|
|
126
|
+
"note": "Use Pinia for new Vue 3 projects",
|
|
127
|
+
"migration": "Pinia is easier and more flexible"
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
"routing": {
|
|
131
|
+
"vue_router": {
|
|
132
|
+
"setup": "import { createRouter, createWebHistory } from 'vue-router'\n\nconst router = createRouter({\n history: createWebHistory(),\n routes: [\n { path: '/', component: Home },\n { path: '/about', component: About },\n { path: '/users/:id', component: User }\n ]\n})",
|
|
133
|
+
"navigation": {
|
|
134
|
+
"declarative": "<router-link to='/about'>About</router-link>",
|
|
135
|
+
"programmatic": "import { useRouter } from 'vue-router'\nconst router = useRouter()\nrouter.push('/about')"
|
|
136
|
+
},
|
|
137
|
+
"params": "import { useRoute } from 'vue-router'\nconst route = useRoute()\nconst userId = route.params.id",
|
|
138
|
+
"guards": {
|
|
139
|
+
"global": "router.beforeEach((to, from) => {\n if (!isAuthenticated && to.meta.requiresAuth) {\n return '/login'\n }\n})",
|
|
140
|
+
"route_level": "{\n path: '/admin',\n component: Admin,\n beforeEnter: (to, from) => {\n // route guard\n }\n}",
|
|
141
|
+
"component_level": "import { onBeforeRouteLeave } from 'vue-router'\n\nonBeforeRouteLeave((to, from) => {\n // component guard\n})"
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
"performance": {
|
|
146
|
+
"v_memo": {
|
|
147
|
+
"description": "Memoize template sub-tree (Vue 3.2+)",
|
|
148
|
+
"example": "<div v-memo='[count]'>\n {{ heavyComputation }}\n</div>",
|
|
149
|
+
"when": "Heavy computations that depend on specific values"
|
|
150
|
+
},
|
|
151
|
+
"v_once": {
|
|
152
|
+
"description": "Render element/component once",
|
|
153
|
+
"example": "<div v-once>{{ staticContent }}</div>",
|
|
154
|
+
"when": "Static content that never changes"
|
|
155
|
+
},
|
|
156
|
+
"keep_alive": {
|
|
157
|
+
"description": "Cache component instances",
|
|
158
|
+
"example": "<keep-alive>\n <component :is='currentTab' />\n</keep-alive>",
|
|
159
|
+
"with_include": "<keep-alive include='a,b' exclude='c'>\n <component :is='view' />\n</keep-alive>",
|
|
160
|
+
"when": "Tabs, dynamic components, preserve state"
|
|
161
|
+
},
|
|
162
|
+
"lazy_loading": {
|
|
163
|
+
"routes": "const User = () => import('./User.vue')",
|
|
164
|
+
"components": "defineAsyncComponent(() => import('./Heavy.vue'))"
|
|
165
|
+
},
|
|
166
|
+
"shallowRef_shallowReactive": {
|
|
167
|
+
"description": "Shallow reactivity for large objects",
|
|
168
|
+
"use_when": "Large data structures, only top level changes",
|
|
169
|
+
"example": "const state = shallowReactive({ nested: { deep: { value: 1 } } })\n// Only state.nested triggers updates, not deep mutations"
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
"typescript": {
|
|
173
|
+
"component_props": "import { defineComponent } from 'vue'\n\nexport default defineComponent({\n props: {\n count: { type: Number, required: true },\n name: String\n }\n})\n\n// Or with script setup:\ninterface Props {\n count: number\n name?: string\n}\n\nconst props = defineProps<Props>()",
|
|
174
|
+
"refs": "const count = ref<number>(0)\nconst input = ref<HTMLInputElement | null>(null)",
|
|
175
|
+
"computed": "const double = computed<number>(() => count.value * 2)",
|
|
176
|
+
"emits": "const emit = defineEmits<{\n update: [id: number, value: string]\n delete: [id: number]\n}>()"
|
|
177
|
+
},
|
|
178
|
+
"directives": {
|
|
179
|
+
"built_in": {
|
|
180
|
+
"v_if": "Conditional rendering (removes from DOM)",
|
|
181
|
+
"v_show": "Toggle display (stays in DOM)",
|
|
182
|
+
"v_for": "List rendering",
|
|
183
|
+
"v_bind": "Bind attributes (:class, :style)",
|
|
184
|
+
"v_on": "Event listeners (@click, @input)",
|
|
185
|
+
"v_model": "Two-way binding",
|
|
186
|
+
"v_slot": "Slot content (#header)"
|
|
187
|
+
},
|
|
188
|
+
"custom_directives": {
|
|
189
|
+
"example": "// v-focus directive\nconst vFocus = {\n mounted: (el) => el.focus()\n}\n\n// Usage:\n<input v-focus />",
|
|
190
|
+
"lifecycle_hooks": ["created", "beforeMount", "mounted", "beforeUpdate", "updated", "beforeUnmount", "unmounted"]
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
"testing": {
|
|
194
|
+
"vitest": {
|
|
195
|
+
"description": "Fast unit test framework for Vite projects",
|
|
196
|
+
"example": "import { describe, it, expect } from 'vitest'\nimport { mount } from '@vue/test-utils'\nimport Counter from './Counter.vue'\n\ndescribe('Counter', () => {\n it('increments count on click', async () => {\n const wrapper = mount(Counter)\n await wrapper.find('button').trigger('click')\n expect(wrapper.text()).toContain('Count: 1')\n })\n})"
|
|
197
|
+
},
|
|
198
|
+
"vue_test_utils": {
|
|
199
|
+
"mount": "Full DOM mounting",
|
|
200
|
+
"shallowMount": "Shallow mounting (stub child components)",
|
|
201
|
+
"find": "Find element by selector",
|
|
202
|
+
"trigger": "Trigger events",
|
|
203
|
+
"setProps": "Update props",
|
|
204
|
+
"example": "const wrapper = mount(Component, {\n props: { count: 0 },\n global: {\n stubs: ['ChildComponent']\n }\n})"
|
|
205
|
+
},
|
|
206
|
+
"e2e": {
|
|
207
|
+
"cypress": "Recommended E2E testing framework",
|
|
208
|
+
"playwright": "Alternative E2E framework"
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
"best_practices": [
|
|
212
|
+
"Use Composition API for new Vue 3 projects",
|
|
213
|
+
"Prefer `<script setup>` syntax for cleaner code",
|
|
214
|
+
"Use ref for primitives, reactive for objects",
|
|
215
|
+
"Create composables for reusable logic",
|
|
216
|
+
"Use Pinia for state management (not Vuex)",
|
|
217
|
+
"Define prop types with TypeScript",
|
|
218
|
+
"Use computed for derived state (not methods)",
|
|
219
|
+
"Keep components small and focused",
|
|
220
|
+
"Use slots for flexible component composition",
|
|
221
|
+
"Lazy load routes and heavy components",
|
|
222
|
+
"Use v-memo for expensive re-renders",
|
|
223
|
+
"Provide meaningful key attributes in v-for",
|
|
224
|
+
"Use teleport for modals/tooltips",
|
|
225
|
+
"Follow Vue style guide naming conventions",
|
|
226
|
+
"Test components with Vue Test Utils + Vitest",
|
|
227
|
+
"Use provide/inject sparingly (prefer props)",
|
|
228
|
+
"Keep watchers simple (or use computed)",
|
|
229
|
+
"Use keep-alive for tab-like interfaces",
|
|
230
|
+
"Memoize expensive computations",
|
|
231
|
+
"Use shallowRef/shallowReactive for large objects"
|
|
232
|
+
],
|
|
233
|
+
"anti_patterns": [
|
|
234
|
+
"Mutating props directly",
|
|
235
|
+
"Using v-if with v-for on same element",
|
|
236
|
+
"Not providing keys in v-for lists",
|
|
237
|
+
"Accessing $refs in computed properties",
|
|
238
|
+
"Overusing watchers (use computed instead)",
|
|
239
|
+
"Deep nesting of components (> 4 levels)",
|
|
240
|
+
"Large components (> 300 lines)",
|
|
241
|
+
"Not using TypeScript in new projects",
|
|
242
|
+
"Using Options API for new Vue 3 projects",
|
|
243
|
+
"Mixing Options API and Composition API",
|
|
244
|
+
"Not using Pinia (using Vuex for Vue 3)",
|
|
245
|
+
"Not lazy loading routes",
|
|
246
|
+
"Ignoring Vue DevTools warnings",
|
|
247
|
+
"Not testing components",
|
|
248
|
+
"Overusing provide/inject (creates hidden dependencies)"
|
|
249
|
+
],
|
|
250
|
+
"migration": {
|
|
251
|
+
"from_vue2": {
|
|
252
|
+
"breaking_changes": [
|
|
253
|
+
"Global API changes (Vue.createApp instead of new Vue)",
|
|
254
|
+
"v-model changes",
|
|
255
|
+
"Filters removed (use computed or methods)",
|
|
256
|
+
"$children removed",
|
|
257
|
+
"Events API removed ($on, $off, $once)"
|
|
258
|
+
],
|
|
259
|
+
"tools": ["@vue/compat (migration build)", "Vue 3 Migration Guide"],
|
|
260
|
+
"strategy": "Incremental migration using compat mode"
|
|
261
|
+
},
|
|
262
|
+
"from_react": {
|
|
263
|
+
"equivalents": {
|
|
264
|
+
"useState": "ref or reactive",
|
|
265
|
+
"useEffect": "watchEffect or watch",
|
|
266
|
+
"useMemo": "computed",
|
|
267
|
+
"useCallback": "Not needed (functions are not recreated)",
|
|
268
|
+
"useContext": "provide/inject",
|
|
269
|
+
"custom_hooks": "composables"
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
},
|
|
273
|
+
"ecosystem": {
|
|
274
|
+
"ui_libraries": ["Vuetify", "Quasar", "Element Plus", "Ant Design Vue", "PrimeVue"],
|
|
275
|
+
"build_tools": ["Vite (recommended)", "Vue CLI (legacy)"],
|
|
276
|
+
"devtools": ["Vue DevTools", "Vite plugin"],
|
|
277
|
+
"meta_frameworks": ["Nuxt 3 (SSR/SSG)", "Quasar (Mobile/Desktop)"]
|
|
278
|
+
}
|
|
279
|
+
}
|