@pythoughts/vue-skills-mcp 0.1.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.
Files changed (208) hide show
  1. package/README.md +63 -0
  2. package/index.mjs +139 -0
  3. package/package.json +34 -0
  4. package/skills/create-adaptable-composable/SKILL.md +76 -0
  5. package/skills/vue-best-practices/SKILL.md +154 -0
  6. package/skills/vue-best-practices/references/animation-class-based-technique.md +254 -0
  7. package/skills/vue-best-practices/references/animation-state-driven-technique.md +291 -0
  8. package/skills/vue-best-practices/references/component-async.md +97 -0
  9. package/skills/vue-best-practices/references/component-data-flow.md +350 -0
  10. package/skills/vue-best-practices/references/component-fallthrough-attrs.md +174 -0
  11. package/skills/vue-best-practices/references/component-keep-alive.md +137 -0
  12. package/skills/vue-best-practices/references/component-slots.md +216 -0
  13. package/skills/vue-best-practices/references/component-suspense.md +228 -0
  14. package/skills/vue-best-practices/references/component-teleport.md +108 -0
  15. package/skills/vue-best-practices/references/component-transition-group.md +128 -0
  16. package/skills/vue-best-practices/references/component-transition.md +125 -0
  17. package/skills/vue-best-practices/references/composables.md +290 -0
  18. package/skills/vue-best-practices/references/directives.md +162 -0
  19. package/skills/vue-best-practices/references/perf-avoid-component-abstraction-in-lists.md +159 -0
  20. package/skills/vue-best-practices/references/perf-v-once-v-memo-directives.md +182 -0
  21. package/skills/vue-best-practices/references/perf-virtualize-large-lists.md +187 -0
  22. package/skills/vue-best-practices/references/plugins.md +166 -0
  23. package/skills/vue-best-practices/references/reactivity.md +346 -0
  24. package/skills/vue-best-practices/references/render-functions.md +201 -0
  25. package/skills/vue-best-practices/references/sfc.md +310 -0
  26. package/skills/vue-best-practices/references/state-management.md +135 -0
  27. package/skills/vue-best-practices/references/updated-hook-performance.md +187 -0
  28. package/skills/vue-debug-guides/SKILL.md +205 -0
  29. package/skills/vue-debug-guides/reference/animation-key-for-rerender.md +160 -0
  30. package/skills/vue-debug-guides/reference/animation-transitiongroup-performance.md +241 -0
  31. package/skills/vue-debug-guides/reference/async-component-error-handling.md +115 -0
  32. package/skills/vue-debug-guides/reference/async-component-keepalive-ref-issue.md +112 -0
  33. package/skills/vue-debug-guides/reference/async-component-suspense-control.md +84 -0
  34. package/skills/vue-debug-guides/reference/async-component-vue-router.md +109 -0
  35. package/skills/vue-debug-guides/reference/attrs-event-listener-merging.md +205 -0
  36. package/skills/vue-debug-guides/reference/checkbox-true-false-value-form-submission.md +118 -0
  37. package/skills/vue-debug-guides/reference/cleanup-side-effects.md +172 -0
  38. package/skills/vue-debug-guides/reference/click-events-on-components.md +180 -0
  39. package/skills/vue-debug-guides/reference/component-naming-conflicts.md +159 -0
  40. package/skills/vue-debug-guides/reference/component-ref-requires-defineexpose.md +176 -0
  41. package/skills/vue-debug-guides/reference/composable-avoid-hidden-side-effects.md +208 -0
  42. package/skills/vue-debug-guides/reference/composable-call-location-restrictions.md +141 -0
  43. package/skills/vue-debug-guides/reference/composable-naming-return-pattern.md +139 -0
  44. package/skills/vue-debug-guides/reference/composable-tovalue-inside-watcheffect.md +182 -0
  45. package/skills/vue-debug-guides/reference/composition-api-not-functional-programming.md +120 -0
  46. package/skills/vue-debug-guides/reference/composition-api-script-setup-async-context.md +203 -0
  47. package/skills/vue-debug-guides/reference/composition-api-vs-react-hooks-differences.md +156 -0
  48. package/skills/vue-debug-guides/reference/computed-array-mutation.md +148 -0
  49. package/skills/vue-debug-guides/reference/computed-conditional-dependencies.md +147 -0
  50. package/skills/vue-debug-guides/reference/computed-no-parameters.md +159 -0
  51. package/skills/vue-debug-guides/reference/computed-no-side-effects.md +107 -0
  52. package/skills/vue-debug-guides/reference/computed-return-value-readonly.md +160 -0
  53. package/skills/vue-debug-guides/reference/configure-app-before-mount.md +89 -0
  54. package/skills/vue-debug-guides/reference/declare-emits-for-documentation.md +212 -0
  55. package/skills/vue-debug-guides/reference/define-expose-before-await.md +192 -0
  56. package/skills/vue-debug-guides/reference/define-model-default-value-sync.md +139 -0
  57. package/skills/vue-debug-guides/reference/defineEmits-must-be-top-level.md +164 -0
  58. package/skills/vue-debug-guides/reference/defineEmits-no-runtime-and-type-mixed.md +170 -0
  59. package/skills/vue-debug-guides/reference/definemodel-object-mutation-no-emit.md +148 -0
  60. package/skills/vue-debug-guides/reference/dom-update-timing-nexttick.md +90 -0
  61. package/skills/vue-debug-guides/reference/dynamic-argument-constraints.md +146 -0
  62. package/skills/vue-debug-guides/reference/dynamic-component-registration-vite.md +147 -0
  63. package/skills/vue-debug-guides/reference/event-modifier-order-matters.md +101 -0
  64. package/skills/vue-debug-guides/reference/exact-modifier-for-precise-shortcuts.md +155 -0
  65. package/skills/vue-debug-guides/reference/fallthrough-attrs-overwrite-vue3.md +159 -0
  66. package/skills/vue-debug-guides/reference/in-dom-template-parsing-caveats.md +149 -0
  67. package/skills/vue-debug-guides/reference/inheritattrs-false-for-wrapper-components.md +230 -0
  68. package/skills/vue-debug-guides/reference/keepalive-router-nested-double-mount.md +222 -0
  69. package/skills/vue-debug-guides/reference/keepalive-transition-memory-leak.md +144 -0
  70. package/skills/vue-debug-guides/reference/keyup-modifier-timing.md +137 -0
  71. package/skills/vue-debug-guides/reference/lifecycle-dom-access-timing.md +216 -0
  72. package/skills/vue-debug-guides/reference/lifecycle-hooks-synchronous-registration.md +156 -0
  73. package/skills/vue-debug-guides/reference/lifecycle-ssr-awareness.md +184 -0
  74. package/skills/vue-debug-guides/reference/local-components-not-in-descendants.md +151 -0
  75. package/skills/vue-debug-guides/reference/mount-return-value.md +88 -0
  76. package/skills/vue-debug-guides/reference/multi-root-component-class-attrs.md +93 -0
  77. package/skills/vue-debug-guides/reference/native-event-collision-with-emits.md +162 -0
  78. package/skills/vue-debug-guides/reference/no-passive-with-prevent.md +141 -0
  79. package/skills/vue-debug-guides/reference/no-v-if-with-v-for.md +136 -0
  80. package/skills/vue-debug-guides/reference/perf-computed-object-stability.md +157 -0
  81. package/skills/vue-debug-guides/reference/perf-props-stability-update-optimization.md +140 -0
  82. package/skills/vue-debug-guides/reference/plugin-global-properties-sparingly.md +109 -0
  83. package/skills/vue-debug-guides/reference/plugin-install-before-mount.md +124 -0
  84. package/skills/vue-debug-guides/reference/plugin-prefer-provide-inject-over-global-properties.md +120 -0
  85. package/skills/vue-debug-guides/reference/plugin-typescript-type-augmentation.md +157 -0
  86. package/skills/vue-debug-guides/reference/prop-defineprops-scope-limitation.md +161 -0
  87. package/skills/vue-debug-guides/reference/provide-inject-debugging-challenges.md +203 -0
  88. package/skills/vue-debug-guides/reference/provide-inject-default-value-factory.md +244 -0
  89. package/skills/vue-debug-guides/reference/provide-inject-reactivity-not-automatic.md +226 -0
  90. package/skills/vue-debug-guides/reference/provide-inject-synchronous-setup.md +235 -0
  91. package/skills/vue-debug-guides/reference/reactive-destructuring.md +89 -0
  92. package/skills/vue-debug-guides/reference/reactivity-debugging-hooks.md +132 -0
  93. package/skills/vue-debug-guides/reference/reactivity-markraw-for-non-reactive.md +149 -0
  94. package/skills/vue-debug-guides/reference/reactivity-proxy-identity-hazard.md +96 -0
  95. package/skills/vue-debug-guides/reference/reactivity-same-tick-batching.md +166 -0
  96. package/skills/vue-debug-guides/reference/ref-value-access.md +61 -0
  97. package/skills/vue-debug-guides/reference/refs-in-collections-need-value.md +81 -0
  98. package/skills/vue-debug-guides/reference/render-function-avoid-internal-vnode-properties.md +151 -0
  99. package/skills/vue-debug-guides/reference/render-function-vnodes-must-be-unique.md +133 -0
  100. package/skills/vue-debug-guides/reference/rendering-render-function-h-import-vue3.md +148 -0
  101. package/skills/vue-debug-guides/reference/rendering-render-function-return-from-setup.md +148 -0
  102. package/skills/vue-debug-guides/reference/rendering-render-function-slots-as-functions.md +168 -0
  103. package/skills/vue-debug-guides/reference/rendering-resolve-component-for-string-names.md +231 -0
  104. package/skills/vue-debug-guides/reference/select-initial-value-ios-bug.md +91 -0
  105. package/skills/vue-debug-guides/reference/self-referencing-component-name.md +157 -0
  106. package/skills/vue-debug-guides/reference/sfc-named-exports-forbidden.md +184 -0
  107. package/skills/vue-debug-guides/reference/sfc-scoped-css-child-component-styling.md +156 -0
  108. package/skills/vue-debug-guides/reference/sfc-scoped-css-dynamic-content.md +193 -0
  109. package/skills/vue-debug-guides/reference/sfc-scoped-css-slot-content.md +242 -0
  110. package/skills/vue-debug-guides/reference/sfc-script-setup-reactivity.md +195 -0
  111. package/skills/vue-debug-guides/reference/slot-forwarding-to-child-components.md +143 -0
  112. package/skills/vue-debug-guides/reference/slot-implicit-default-content.md +155 -0
  113. package/skills/vue-debug-guides/reference/slot-name-reserved-prop.md +109 -0
  114. package/skills/vue-debug-guides/reference/slot-named-scoped-explicit-default.md +95 -0
  115. package/skills/vue-debug-guides/reference/slot-render-scope-parent-only.md +135 -0
  116. package/skills/vue-debug-guides/reference/slot-v-slot-on-components-or-templates-only.md +122 -0
  117. package/skills/vue-debug-guides/reference/ssr-hydration-mismatch-causes.md +280 -0
  118. package/skills/vue-debug-guides/reference/ssr-platform-specific-apis.md +256 -0
  119. package/skills/vue-debug-guides/reference/state-ssr-cross-request-pollution.md +276 -0
  120. package/skills/vue-debug-guides/reference/suspense-no-builtin-error-handling.md +127 -0
  121. package/skills/vue-debug-guides/reference/suspense-ssr-hydration-issues.md +159 -0
  122. package/skills/vue-debug-guides/reference/tailwind-dynamic-class-generation.md +144 -0
  123. package/skills/vue-debug-guides/reference/teleport-scoped-styles-limitation.md +191 -0
  124. package/skills/vue-debug-guides/reference/teleport-ssr-hydration.md +152 -0
  125. package/skills/vue-debug-guides/reference/teleport-target-must-exist.md +113 -0
  126. package/skills/vue-debug-guides/reference/template-expressions-restrictions.md +114 -0
  127. package/skills/vue-debug-guides/reference/template-functions-no-side-effects.md +187 -0
  128. package/skills/vue-debug-guides/reference/template-ref-null-with-v-if.md +123 -0
  129. package/skills/vue-debug-guides/reference/template-ref-unwrapping-top-level.md +104 -0
  130. package/skills/vue-debug-guides/reference/template-ref-v-for-order.md +172 -0
  131. package/skills/vue-debug-guides/reference/textarea-no-interpolation.md +72 -0
  132. package/skills/vue-debug-guides/reference/transition-group-flip-inline-elements.md +152 -0
  133. package/skills/vue-debug-guides/reference/transition-group-move-animation-position-absolute.md +130 -0
  134. package/skills/vue-debug-guides/reference/transition-group-no-default-wrapper-vue3.md +152 -0
  135. package/skills/vue-debug-guides/reference/transition-js-hooks-done-callback.md +251 -0
  136. package/skills/vue-debug-guides/reference/transition-nested-duration.md +182 -0
  137. package/skills/vue-debug-guides/reference/transition-reusable-scoped-style.md +245 -0
  138. package/skills/vue-debug-guides/reference/transition-router-view-appear.md +193 -0
  139. package/skills/vue-debug-guides/reference/transition-type-when-mixed.md +172 -0
  140. package/skills/vue-debug-guides/reference/transition-unmount-hook-timing.md +149 -0
  141. package/skills/vue-debug-guides/reference/ts-defineprops-boolean-default-false.md +225 -0
  142. package/skills/vue-debug-guides/reference/ts-defineprops-imported-types-limitations.md +281 -0
  143. package/skills/vue-debug-guides/reference/ts-event-handler-explicit-typing.md +213 -0
  144. package/skills/vue-debug-guides/reference/ts-reactive-no-generic-argument.md +196 -0
  145. package/skills/vue-debug-guides/reference/ts-shallowref-for-dynamic-components.md +218 -0
  146. package/skills/vue-debug-guides/reference/ts-template-ref-null-handling.md +249 -0
  147. package/skills/vue-debug-guides/reference/ts-template-type-casting.md +214 -0
  148. package/skills/vue-debug-guides/reference/ts-withdefaults-mutable-factory-function.md +171 -0
  149. package/skills/vue-debug-guides/reference/undeclared-emits-double-firing.md +195 -0
  150. package/skills/vue-debug-guides/reference/use-template-ref-vue35.md +158 -0
  151. package/skills/vue-debug-guides/reference/v-else-must-follow-v-if.md +136 -0
  152. package/skills/vue-debug-guides/reference/v-for-component-props.md +95 -0
  153. package/skills/vue-debug-guides/reference/v-for-computed-reverse-sort.md +86 -0
  154. package/skills/vue-debug-guides/reference/v-for-key-attribute.md +90 -0
  155. package/skills/vue-debug-guides/reference/v-for-range-starts-at-one.md +66 -0
  156. package/skills/vue-debug-guides/reference/v-if-null-check-order.md +171 -0
  157. package/skills/vue-debug-guides/reference/v-model-ignores-html-attributes.md +83 -0
  158. package/skills/vue-debug-guides/reference/v-model-ime-composition.md +83 -0
  159. package/skills/vue-debug-guides/reference/v-model-number-modifier-behavior.md +124 -0
  160. package/skills/vue-debug-guides/reference/v-show-template-limitation.md +124 -0
  161. package/skills/vue-debug-guides/reference/watch-async-cleanup.md +180 -0
  162. package/skills/vue-debug-guides/reference/watch-async-creation-memory-leak.md +176 -0
  163. package/skills/vue-debug-guides/reference/watch-deep-same-object-reference.md +165 -0
  164. package/skills/vue-debug-guides/reference/watch-flush-timing.md +189 -0
  165. package/skills/vue-debug-guides/reference/watch-reactive-property-getter.md +108 -0
  166. package/skills/vue-debug-guides/reference/watcheffect-async-dependency-tracking.md +173 -0
  167. package/skills/vue-debug-guides/reference/watcheffect-flush-post-for-refs.md +176 -0
  168. package/skills/vue-jsx-best-practices/SKILL.md +12 -0
  169. package/skills/vue-jsx-best-practices/reference/render-function-jsx-vue-vs-react.md +141 -0
  170. package/skills/vue-options-api-best-practices/SKILL.md +23 -0
  171. package/skills/vue-options-api-best-practices/reference/no-arrow-functions-in-lifecycle-hooks.md +95 -0
  172. package/skills/vue-options-api-best-practices/reference/no-arrow-functions-in-methods.md +68 -0
  173. package/skills/vue-options-api-best-practices/reference/stateful-methods-lifecycle.md +61 -0
  174. package/skills/vue-options-api-best-practices/reference/ts-options-api-arrow-functions-validators.md +141 -0
  175. package/skills/vue-options-api-best-practices/reference/ts-options-api-computed-return-types.md +192 -0
  176. package/skills/vue-options-api-best-practices/reference/ts-options-api-proptype-complex-types.md +212 -0
  177. package/skills/vue-options-api-best-practices/reference/ts-options-api-provide-inject-limitations.md +135 -0
  178. package/skills/vue-options-api-best-practices/reference/ts-options-api-type-event-handlers.md +202 -0
  179. package/skills/vue-options-api-best-practices/reference/ts-options-api-use-definecomponent.md +172 -0
  180. package/skills/vue-options-api-best-practices/reference/ts-strict-mode-options-api.md +197 -0
  181. package/skills/vue-pinia-best-practices/SKILL.md +21 -0
  182. package/skills/vue-pinia-best-practices/reference/pinia-no-active-pinia-error.md +248 -0
  183. package/skills/vue-pinia-best-practices/reference/pinia-setup-store-return-all-state.md +227 -0
  184. package/skills/vue-pinia-best-practices/reference/pinia-store-destructuring-breaks-reactivity.md +193 -0
  185. package/skills/vue-pinia-best-practices/reference/state-url-for-ephemeral-filters.md +238 -0
  186. package/skills/vue-pinia-best-practices/reference/state-use-pinia-for-large-apps.md +262 -0
  187. package/skills/vue-pinia-best-practices/reference/store-method-binding-parentheses.md +191 -0
  188. package/skills/vue-router-best-practices/SKILL.md +23 -0
  189. package/skills/vue-router-best-practices/reference/router-beforeenter-no-param-trigger.md +167 -0
  190. package/skills/vue-router-best-practices/reference/router-beforerouteenter-no-this.md +176 -0
  191. package/skills/vue-router-best-practices/reference/router-guard-async-await-pattern.md +227 -0
  192. package/skills/vue-router-best-practices/reference/router-navigation-guard-infinite-loop.md +187 -0
  193. package/skills/vue-router-best-practices/reference/router-navigation-guard-next-deprecated.md +150 -0
  194. package/skills/vue-router-best-practices/reference/router-param-change-no-lifecycle.md +181 -0
  195. package/skills/vue-router-best-practices/reference/router-simple-routing-cleanup.md +209 -0
  196. package/skills/vue-router-best-practices/reference/router-use-vue-router-for-production.md +183 -0
  197. package/skills/vue-testing-best-practices/SKILL.md +29 -0
  198. package/skills/vue-testing-best-practices/reference/async-component-testing.md +163 -0
  199. package/skills/vue-testing-best-practices/reference/teleport-testing-complexity.md +158 -0
  200. package/skills/vue-testing-best-practices/reference/testing-async-await-flushpromises.md +175 -0
  201. package/skills/vue-testing-best-practices/reference/testing-browser-vs-node-runners.md +208 -0
  202. package/skills/vue-testing-best-practices/reference/testing-component-blackbox-approach.md +144 -0
  203. package/skills/vue-testing-best-practices/reference/testing-composables-helper-wrapper.md +238 -0
  204. package/skills/vue-testing-best-practices/reference/testing-e2e-playwright-recommended.md +242 -0
  205. package/skills/vue-testing-best-practices/reference/testing-no-snapshot-only.md +197 -0
  206. package/skills/vue-testing-best-practices/reference/testing-pinia-store-setup.md +228 -0
  207. package/skills/vue-testing-best-practices/reference/testing-suspense-async-components.md +229 -0
  208. package/skills/vue-testing-best-practices/reference/testing-vitest-recommended-for-vue.md +204 -0
@@ -0,0 +1,143 @@
1
+ ---
2
+ title: Forward Slots to Child Components Correctly
3
+ impact: MEDIUM
4
+ impactDescription: Wrapper components that don't forward slots break slot functionality for consumers
5
+ type: best-practice
6
+ tags: [vue3, slots, component-composition, wrapper-components, slot-forwarding]
7
+ ---
8
+
9
+ # Forward Slots to Child Components Correctly
10
+
11
+ **Impact: MEDIUM** - When creating wrapper components that enhance or extend other components, you need to forward slots from the parent to the wrapped child. Without proper slot forwarding, consumers of your wrapper cannot customize the inner component's slots.
12
+
13
+ ## Task Checklist
14
+
15
+ - [ ] Use `v-for` with `$slots` to iterate over all provided slots
16
+ - [ ] Use dynamic slot names with `v-slot:[slotName]`
17
+ - [ ] Pass slot props through with `v-bind="slotProps"`
18
+ - [ ] Handle cases where slotProps might be undefined
19
+
20
+ **Basic Slot Forwarding Pattern:**
21
+ ```vue
22
+ <!-- EnhancedButton.vue - Wrapper component -->
23
+ <script setup>
24
+ import BaseButton from './BaseButton.vue'
25
+ </script>
26
+
27
+ <template>
28
+ <div class="button-wrapper">
29
+ <BaseButton v-bind="$attrs">
30
+ <!-- Forward all slots to BaseButton -->
31
+ <template v-for="(_, slotName) in $slots" v-slot:[slotName]="slotProps">
32
+ <slot :name="slotName" v-bind="slotProps ?? {}" />
33
+ </template>
34
+ </BaseButton>
35
+ </div>
36
+ </template>
37
+ ```
38
+
39
+ **Usage:**
40
+ ```vue
41
+ <script setup>
42
+ import EnhancedButton from './EnhancedButton.vue'
43
+ </script>
44
+
45
+ <template>
46
+ <!-- Slots pass through to BaseButton -->
47
+ <EnhancedButton>
48
+ <template #icon>
49
+ <IconCheck />
50
+ </template>
51
+ <template #default>
52
+ Click me
53
+ </template>
54
+ </EnhancedButton>
55
+ </template>
56
+ ```
57
+
58
+ ## Handling Scoped Slots
59
+
60
+ When the child component provides slot props, you must forward them:
61
+
62
+ ```vue
63
+ <!-- DataTableWrapper.vue -->
64
+ <script setup>
65
+ import DataTable from './DataTable.vue'
66
+
67
+ const props = defineProps(['data'])
68
+ </script>
69
+
70
+ <template>
71
+ <div class="table-container">
72
+ <DataTable :items="data">
73
+ <!-- Forward slots including scoped slot props -->
74
+ <template v-for="(_, slotName) in $slots" v-slot:[slotName]="slotProps">
75
+ <slot :name="slotName" v-bind="slotProps ?? {}" />
76
+ </template>
77
+ </DataTable>
78
+ </div>
79
+ </template>
80
+ ```
81
+
82
+ ```vue
83
+ <!-- Consumer can use scoped slot props -->
84
+ <DataTableWrapper :data="users">
85
+ <template #row="{ item, index }">
86
+ <tr>
87
+ <td>{{ index + 1 }}</td>
88
+ <td>{{ item.name }}</td>
89
+ </tr>
90
+ </template>
91
+ </DataTableWrapper>
92
+ ```
93
+
94
+ ## Alternative: Handling Undefined slotProps
95
+
96
+ Some scenarios require checking if slotProps exists:
97
+
98
+ ```vue
99
+ <template>
100
+ <ChildComponent>
101
+ <template v-for="(_, name) in $slots" v-slot:[name]="slotProps">
102
+ <!-- Handle both scoped and non-scoped slots -->
103
+ <slot v-if="slotProps" :name="name" v-bind="slotProps" />
104
+ <slot v-else :name="name" />
105
+ </template>
106
+ </ChildComponent>
107
+ </template>
108
+ ```
109
+
110
+ ## Forwarding Specific Slots Only
111
+
112
+ If you only want to forward certain slots:
113
+
114
+ ```vue
115
+ <template>
116
+ <ChildComponent>
117
+ <!-- Only forward header and footer slots -->
118
+ <template v-if="$slots.header" #header="slotProps">
119
+ <slot name="header" v-bind="slotProps ?? {}" />
120
+ </template>
121
+
122
+ <template v-if="$slots.footer" #footer="slotProps">
123
+ <slot name="footer" v-bind="slotProps ?? {}" />
124
+ </template>
125
+
126
+ <!-- Default slot handled differently -->
127
+ <slot />
128
+ </ChildComponent>
129
+ </template>
130
+ ```
131
+
132
+ ## Common Mistakes
133
+
134
+ | Mistake | Problem | Solution |
135
+ |---------|---------|----------|
136
+ | Not using `v-bind="slotProps"` | Scoped slot data lost | Always bind slotProps |
137
+ | Forgetting `?? {}` or null check | Error when slotProps undefined | Add nullish coalescing |
138
+ | Static slot names in loop | Only forwards one slot | Use `v-slot:[slotName]` dynamic syntax |
139
+ | Missing `v-for` key warning | Vue warning (non-critical) | Keys not needed for slot functions |
140
+
141
+ ## Reference
142
+ - [Vue Land FAQ - Forwarding Slots](https://vue-land.github.io/faq/forwarding-slots)
143
+ - [Vue.js Slots - Scoped Slots](https://vuejs.org/guide/components/slots.html#scoped-slots)
@@ -0,0 +1,155 @@
1
+ ---
2
+ title: Non-Template Content Is Implicitly Default Slot Content
3
+ impact: LOW
4
+ impactDescription: Unexpected content placement when mixing named slots with loose content
5
+ type: gotcha
6
+ tags: [vue3, slots, named-slots, default-slot, implicit-behavior]
7
+ ---
8
+
9
+ # Non-Template Content Is Implicitly Default Slot Content
10
+
11
+ **Impact: LOW** - When using named slots, any top-level content not wrapped in a `<template>` tag is automatically treated as default slot content. This implicit behavior can cause confusion about where content will render.
12
+
13
+ ## Task Checklist
14
+
15
+ - [ ] Understand that loose content goes to the default slot
16
+ - [ ] Use explicit `<template #default>` when clarity matters
17
+ - [ ] Keep slot content organization intentional
18
+
19
+ **The Implicit Behavior:**
20
+ ```vue
21
+ <script setup>
22
+ import BaseLayout from './BaseLayout.vue'
23
+ </script>
24
+
25
+ <template>
26
+ <BaseLayout>
27
+ <template #header>
28
+ <h1>Page Title</h1>
29
+ </template>
30
+
31
+ <!-- These are IMPLICITLY in the default slot -->
32
+ <p>First paragraph of main content.</p>
33
+ <p>Second paragraph of main content.</p>
34
+
35
+ <template #footer>
36
+ <p>Footer content</p>
37
+ </template>
38
+ </BaseLayout>
39
+ </template>
40
+ ```
41
+
42
+ The two `<p>` elements are automatically placed in `<slot>` (the default slot) in the child component.
43
+
44
+ **Equivalent Explicit Version:**
45
+ ```vue
46
+ <template>
47
+ <BaseLayout>
48
+ <template #header>
49
+ <h1>Page Title</h1>
50
+ </template>
51
+
52
+ <!-- Explicit default slot -->
53
+ <template #default>
54
+ <p>First paragraph of main content.</p>
55
+ <p>Second paragraph of main content.</p>
56
+ </template>
57
+
58
+ <template #footer>
59
+ <p>Footer content</p>
60
+ </template>
61
+ </BaseLayout>
62
+ </template>
63
+ ```
64
+
65
+ ## When Implicit Behavior Causes Confusion
66
+
67
+ **Scattered Content:**
68
+ ```vue
69
+ <template>
70
+ <BaseLayout>
71
+ <template #header>
72
+ <h1>Title</h1>
73
+ </template>
74
+
75
+ <p>Content A</p> <!-- Goes to default slot -->
76
+
77
+ <template #sidebar>
78
+ <nav>Navigation</nav>
79
+ </template>
80
+
81
+ <p>Content B</p> <!-- Also goes to default slot! -->
82
+
83
+ <template #footer>
84
+ <p>Footer</p>
85
+ </template>
86
+
87
+ <p>Content C</p> <!-- Also goes to default slot! -->
88
+ </BaseLayout>
89
+ </template>
90
+ ```
91
+
92
+ All three `<p>` elements end up in the default slot together, which may not be the intended order or grouping.
93
+
94
+ **Clearer with Explicit Default:**
95
+ ```vue
96
+ <template>
97
+ <BaseLayout>
98
+ <template #header>
99
+ <h1>Title</h1>
100
+ </template>
101
+
102
+ <template #default>
103
+ <p>Content A</p>
104
+ <p>Content B</p>
105
+ <p>Content C</p>
106
+ </template>
107
+
108
+ <template #sidebar>
109
+ <nav>Navigation</nav>
110
+ </template>
111
+
112
+ <template #footer>
113
+ <p>Footer</p>
114
+ </template>
115
+ </BaseLayout>
116
+ </template>
117
+ ```
118
+
119
+ ## Best Practices
120
+
121
+ | Scenario | Recommendation |
122
+ |----------|---------------|
123
+ | Only default slot used | Implicit is fine |
124
+ | Mixed named + default slots | Consider explicit `#default` |
125
+ | Complex layouts | Always use explicit templates |
126
+ | Team/shared codebase | Prefer explicit for clarity |
127
+
128
+ ## The Child Component
129
+
130
+ ```vue
131
+ <!-- BaseLayout.vue -->
132
+ <template>
133
+ <div class="layout">
134
+ <header>
135
+ <slot name="header"></slot>
136
+ </header>
137
+
138
+ <aside>
139
+ <slot name="sidebar"></slot>
140
+ </aside>
141
+
142
+ <main>
143
+ <!-- All implicit content ends up here -->
144
+ <slot></slot>
145
+ </main>
146
+
147
+ <footer>
148
+ <slot name="footer"></slot>
149
+ </footer>
150
+ </div>
151
+ </template>
152
+ ```
153
+
154
+ ## Reference
155
+ - [Vue.js Slots - Named Slots](https://vuejs.org/guide/components/slots.html#named-slots)
@@ -0,0 +1,109 @@
1
+ ---
2
+ title: Slot Name is Reserved and Not Included in Slot Props
3
+ impact: LOW
4
+ impactDescription: Expecting 'name' in scoped slot props when it's reserved causes confusion
5
+ type: gotcha
6
+ tags: [vue3, slots, scoped-slots, reserved-props, naming]
7
+ ---
8
+
9
+ # Slot Name is Reserved and Not Included in Slot Props
10
+
11
+ **Impact: LOW** - When using scoped slots, the `name` attribute on the `<slot>` element is reserved for identifying the slot. It is not passed as part of the slot props to the parent component.
12
+
13
+ ## Task Checklist
14
+
15
+ - [ ] Don't expect `name` in slot props - it's reserved
16
+ - [ ] Use a different prop name if you need to pass a name value
17
+ - [ ] Remember only explicitly bound attributes become slot props
18
+
19
+ **Incorrect Expectation:**
20
+ ```vue
21
+ <!-- ChildComponent.vue -->
22
+ <template>
23
+ <div>
24
+ <slot name="header" title="Welcome"></slot>
25
+ </div>
26
+ </template>
27
+ ```
28
+
29
+ ```vue
30
+ <!-- ParentComponent.vue -->
31
+ <ChildComponent>
32
+ <template #header="props">
33
+ <!-- props = { title: "Welcome" } -->
34
+ <!-- 'name' is NOT included! -->
35
+ {{ props.name }} <!-- undefined -->
36
+ {{ props.title }} <!-- "Welcome" -->
37
+ </template>
38
+ </ChildComponent>
39
+ ```
40
+
41
+ **If You Need to Pass a "Name" Value:**
42
+ ```vue
43
+ <!-- ChildComponent.vue -->
44
+ <template>
45
+ <div>
46
+ <!-- Use a different prop name like 'slotName' or 'label' -->
47
+ <slot name="header" :label="slotLabel" :title="title"></slot>
48
+ </div>
49
+ </template>
50
+
51
+ <script setup>
52
+ const slotLabel = 'header'
53
+ const title = 'Welcome'
54
+ </script>
55
+ ```
56
+
57
+ ```vue
58
+ <!-- ParentComponent.vue -->
59
+ <ChildComponent>
60
+ <template #header="{ label, title }">
61
+ <h2>{{ title }}</h2>
62
+ <span>Section: {{ label }}</span>
63
+ </template>
64
+ </ChildComponent>
65
+ ```
66
+
67
+ ## What Gets Passed as Slot Props
68
+
69
+ | Attribute on `<slot>` | Passed to Parent? |
70
+ |----------------------|-------------------|
71
+ | `name` | No (reserved for slot identification) |
72
+ | `:text="message"` | Yes, as `text` |
73
+ | `:count="5"` | Yes, as `count` |
74
+ | `v-bind="object"` | Yes, spreads object properties |
75
+ | `class="..."` | No (not bound with `:`) |
76
+
77
+ ## Multiple Named Slots Example
78
+
79
+ ```vue
80
+ <!-- TabPanel.vue -->
81
+ <template>
82
+ <div class="tabs">
83
+ <slot name="tab1" :active="activeTab === 1" :label="'First Tab'"></slot>
84
+ <slot name="tab2" :active="activeTab === 2" :label="'Second Tab'"></slot>
85
+ </div>
86
+ </template>
87
+
88
+ <script setup>
89
+ import { ref } from 'vue'
90
+ const activeTab = ref(1)
91
+ </script>
92
+ ```
93
+
94
+ ```vue
95
+ <!-- Usage -->
96
+ <TabPanel>
97
+ <template #tab1="{ active, label }">
98
+ <!-- 'name' not available, but 'label' is -->
99
+ <button :class="{ active }">{{ label }}</button>
100
+ </template>
101
+
102
+ <template #tab2="{ active, label }">
103
+ <button :class="{ active }">{{ label }}</button>
104
+ </template>
105
+ </TabPanel>
106
+ ```
107
+
108
+ ## Reference
109
+ - [Vue.js Slots - Scoped Slots](https://vuejs.org/guide/components/slots.html#scoped-slots)
@@ -0,0 +1,95 @@
1
+ ---
2
+ title: Use Explicit Default Template When Mixing Named and Scoped Slots
3
+ impact: HIGH
4
+ impactDescription: Mixing v-slot on component with named slots inside causes ambiguous scope and compilation errors
5
+ type: gotcha
6
+ tags: [vue3, slots, scoped-slots, named-slots, compilation-error]
7
+ ---
8
+
9
+ # Use Explicit Default Template When Mixing Named and Scoped Slots
10
+
11
+ **Impact: HIGH** - When a component uses both the default scoped slot and named slots, you must use an explicit `<template #default>` for the default slot. Using `v-slot` directly on the component while having nested named slot templates causes scope ambiguity and compilation errors.
12
+
13
+ ## Task Checklist
14
+
15
+ - [ ] When using named slots alongside a default slot with props, always use explicit `<template #default>`
16
+ - [ ] Never mix `v-slot` on the component element with `<template #name>` inside
17
+ - [ ] Keep slot scope clear and unambiguous
18
+
19
+ **Incorrect:**
20
+ ```vue
21
+ <script setup>
22
+ import MyComponent from './MyComponent.vue'
23
+ </script>
24
+
25
+ <template>
26
+ <!-- BAD: v-slot on component + named template inside causes ambiguity -->
27
+ <MyComponent v-slot="{ message }">
28
+ <p>{{ message }}</p>
29
+
30
+ <template #footer>
31
+ <!-- Ambiguous: Is 'message' available here? Vue can't determine -->
32
+ <p>Footer: {{ message }}</p>
33
+ </template>
34
+ </MyComponent>
35
+ </template>
36
+ ```
37
+
38
+ This causes a compilation error because Vue cannot determine:
39
+ 1. Whether `message` from the default slot should be available in the footer slot
40
+ 2. Which scope applies to the non-template content
41
+
42
+ **Correct:**
43
+ ```vue
44
+ <script setup>
45
+ import MyComponent from './MyComponent.vue'
46
+ </script>
47
+
48
+ <template>
49
+ <!-- GOOD: Explicit template for each slot with clear scope -->
50
+ <MyComponent>
51
+ <template #default="{ message }">
52
+ <p>{{ message }}</p>
53
+ </template>
54
+
55
+ <template #footer>
56
+ <!-- Clear: footer slot has its own scope, no access to default's 'message' -->
57
+ <p>Footer content here</p>
58
+ </template>
59
+ </MyComponent>
60
+ </template>
61
+ ```
62
+
63
+ **Correct - When Footer Also Has Props:**
64
+ ```vue
65
+ <script setup>
66
+ import MyComponent from './MyComponent.vue'
67
+ </script>
68
+
69
+ <template>
70
+ <MyComponent>
71
+ <template #default="{ message }">
72
+ <p>{{ message }}</p>
73
+ </template>
74
+
75
+ <template #footer="{ year }">
76
+ <!-- Each slot receives its own props -->
77
+ <p>Copyright {{ year }}</p>
78
+ </template>
79
+ </MyComponent>
80
+ </template>
81
+ ```
82
+
83
+ ## The Rule
84
+
85
+ When you have **any** named slots (`<template #name>`), always use explicit templates for **all** slots, including the default slot. This makes scope boundaries clear and prevents compilation errors.
86
+
87
+ | Pattern | Valid? | Notes |
88
+ |---------|--------|-------|
89
+ | `v-slot` on component only | Yes | Single default scoped slot |
90
+ | Named templates only | Yes | Multiple named slots |
91
+ | `v-slot` on component + named templates | No | Ambiguous scope |
92
+ | All explicit templates | Yes | Clear scope for each slot |
93
+
94
+ ## Reference
95
+ - [Vue.js Slots - Named Scoped Slots](https://vuejs.org/guide/components/slots.html#named-scoped-slots)
@@ -0,0 +1,135 @@
1
+ ---
2
+ title: Slot Content Only Has Access to Parent Component Scope
3
+ impact: HIGH
4
+ impactDescription: Attempting to access child component data in slot content results in undefined values or errors
5
+ type: gotcha
6
+ tags: [vue3, slots, scope, reactivity, common-mistake]
7
+ ---
8
+
9
+ # Slot Content Only Has Access to Parent Component Scope
10
+
11
+ **Impact: HIGH** - Slot content is compiled in the parent component's scope and cannot access data defined in the child component. This follows JavaScript's lexical scoping rules and is a common source of confusion.
12
+
13
+ When you provide content for a slot, that content is defined in your parent template and can only access data available in the parent component. The child component's internal state is not accessible unless explicitly passed via scoped slots.
14
+
15
+ ## Task Checklist
16
+
17
+ - [ ] Remember that slot content is compiled in parent scope
18
+ - [ ] Never try to access child component data directly in slot content
19
+ - [ ] Use scoped slots when child data needs to be exposed to parent
20
+ - [ ] Check that all template expressions reference data available in the current component
21
+
22
+ **Incorrect:**
23
+ ```vue
24
+ <!-- Parent.vue -->
25
+ <script setup>
26
+ import SubmitButton from './SubmitButton.vue'
27
+ </script>
28
+
29
+ <template>
30
+ <!-- BAD: Trying to access child's buttonText - this will be undefined -->
31
+ <SubmitButton>{{ buttonText }}</SubmitButton>
32
+
33
+ <!-- BAD: Trying to access child's isLoading state -->
34
+ <SubmitButton>
35
+ <span v-if="isLoading">Loading...</span>
36
+ <span v-else>Submit</span>
37
+ </SubmitButton>
38
+ </template>
39
+ ```
40
+
41
+ ```vue
42
+ <!-- SubmitButton.vue (Child) -->
43
+ <script setup>
44
+ import { ref } from 'vue'
45
+
46
+ const buttonText = ref('Click me') // Not accessible in parent's slot content
47
+ const isLoading = ref(false) // Not accessible in parent's slot content
48
+ </script>
49
+
50
+ <template>
51
+ <button>
52
+ <slot></slot>
53
+ </button>
54
+ </template>
55
+ ```
56
+
57
+ **Correct - Use Scoped Slots:**
58
+ ```vue
59
+ <!-- SubmitButton.vue (Child) - Expose data via slot props -->
60
+ <script setup>
61
+ import { ref } from 'vue'
62
+
63
+ const buttonText = ref('Click me')
64
+ const isLoading = ref(false)
65
+ </script>
66
+
67
+ <template>
68
+ <button>
69
+ <!-- Pass child data as slot props -->
70
+ <slot :text="buttonText" :loading="isLoading"></slot>
71
+ </button>
72
+ </template>
73
+ ```
74
+
75
+ ```vue
76
+ <!-- Parent.vue -->
77
+ <script setup>
78
+ import SubmitButton from './SubmitButton.vue'
79
+ </script>
80
+
81
+ <template>
82
+ <!-- GOOD: Receive child data via scoped slot -->
83
+ <SubmitButton v-slot="{ text, loading }">
84
+ <span v-if="loading">Loading...</span>
85
+ <span v-else>{{ text }}</span>
86
+ </SubmitButton>
87
+ </template>
88
+ ```
89
+
90
+ **Correct - Use Parent Data:**
91
+ ```vue
92
+ <!-- Parent.vue -->
93
+ <script setup>
94
+ import { ref } from 'vue'
95
+ import SubmitButton from './SubmitButton.vue'
96
+
97
+ // Define data in parent where slot content is compiled
98
+ const message = ref('Submit Form')
99
+ const isSubmitting = ref(false)
100
+ </script>
101
+
102
+ <template>
103
+ <!-- GOOD: Using parent's own data in slot content -->
104
+ <SubmitButton>
105
+ <span v-if="isSubmitting">Processing...</span>
106
+ <span v-else>{{ message }}</span>
107
+ </SubmitButton>
108
+ </template>
109
+ ```
110
+
111
+ ## The Function Analogy
112
+
113
+ Think of slots as function parameters:
114
+
115
+ ```javascript
116
+ // Slot content is like a callback defined in parent scope
117
+ function Parent() {
118
+ const parentData = 'Hello'
119
+
120
+ // This callback can only see parentData, not childData
121
+ Child((slotProps) => {
122
+ return parentData + (slotProps?.text || '')
123
+ })
124
+ }
125
+
126
+ function Child(slotCallback) {
127
+ const childData = 'World' // Not visible to callback
128
+
129
+ // Must explicitly pass data via slot props
130
+ return slotCallback({ text: childData })
131
+ }
132
+ ```
133
+
134
+ ## Reference
135
+ - [Vue.js Slots - Render Scope](https://vuejs.org/guide/components/slots.html#render-scope)