@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,91 @@
1
+ ---
2
+ title: Select Element iOS Bug - Always Include Disabled Placeholder Option
3
+ impact: HIGH
4
+ impactDescription: On iOS, users cannot select the first option if v-model initial value doesn't match any option
5
+ type: capability
6
+ tags: [vue3, v-model, forms, select, ios, mobile, accessibility]
7
+ ---
8
+
9
+ # Select Element iOS Bug - Always Include Disabled Placeholder Option
10
+
11
+ **Impact: HIGH** - When a `<select>` element's v-model initial value doesn't match any option, iOS renders it as "unselected" and users CANNOT select the first item. iOS doesn't fire a change event when selecting an already-visually-selected option, leaving users stuck.
12
+
13
+ This is a platform-specific bug that only manifests on iOS Safari. Desktop browsers and Android handle this gracefully, making it easy to miss during development. The fix is simple: always include a disabled placeholder option.
14
+
15
+ ## Task Checklist
16
+
17
+ - [ ] Always add a disabled placeholder option with empty value to select elements
18
+ - [ ] Ensure v-model initial value is empty string to match the placeholder
19
+ - [ ] Test select inputs on iOS devices or simulators
20
+ - [ ] Consider this for any user-facing forms, especially on mobile-first apps
21
+
22
+ **Problem - iOS users cannot select first option:**
23
+ ```html
24
+ <script setup>
25
+ import { ref } from 'vue'
26
+
27
+ // Initial value is empty string, doesn't match any option
28
+ const selected = ref('')
29
+ </script>
30
+
31
+ <template>
32
+ <!-- PROBLEM: On iOS, "Apple" appears selected but user cannot actually select it -->
33
+ <!-- Tapping "Apple" does nothing because iOS doesn't fire change event -->
34
+ <select v-model="selected">
35
+ <option value="apple">Apple</option>
36
+ <option value="banana">Banana</option>
37
+ <option value="orange">Orange</option>
38
+ </select>
39
+
40
+ <!-- selected remains '' even though "Apple" appears highlighted -->
41
+ </template>
42
+ ```
43
+
44
+ **Solution - Add disabled placeholder option:**
45
+ ```html
46
+ <script setup>
47
+ import { ref } from 'vue'
48
+
49
+ const selected = ref('') // Matches the placeholder option
50
+ </script>
51
+
52
+ <template>
53
+ <!-- CORRECT: Disabled placeholder ensures user must actively select -->
54
+ <select v-model="selected">
55
+ <option disabled value="">Please select a fruit</option>
56
+ <option value="apple">Apple</option>
57
+ <option value="banana">Banana</option>
58
+ <option value="orange">Orange</option>
59
+ </select>
60
+ </template>
61
+ ```
62
+
63
+ ```html
64
+ <!-- Variant with required attribute for form validation -->
65
+ <select v-model="selected" required>
66
+ <option disabled value="">-- Select an option --</option>
67
+ <option value="a">Option A</option>
68
+ <option value="b">Option B</option>
69
+ </select>
70
+ ```
71
+
72
+ ```html
73
+ <!-- If you MUST have a pre-selected default, set the initial value to match -->
74
+ <script setup>
75
+ import { ref } from 'vue'
76
+
77
+ // Set initial value to match an actual option
78
+ const country = ref('us') // Pre-selects "United States"
79
+ </script>
80
+
81
+ <template>
82
+ <select v-model="country">
83
+ <option value="us">United States</option>
84
+ <option value="uk">United Kingdom</option>
85
+ <option value="ca">Canada</option>
86
+ </select>
87
+ </template>
88
+ ```
89
+
90
+ ## Reference
91
+ - [Vue.js Form Input Bindings - Select](https://vuejs.org/guide/essentials/forms.html#select)
@@ -0,0 +1,157 @@
1
+ ---
2
+ title: Self-Referencing Components Use Filename as Implicit Name
3
+ impact: LOW
4
+ impactDescription: Understanding this avoids confusion with recursive components
5
+ type: gotcha
6
+ tags: [vue3, component-registration, self-reference, recursive-components, sfc]
7
+ ---
8
+
9
+ # Self-Referencing Components Use Filename as Implicit Name
10
+
11
+ **Impact: LOW** - In Single-File Components (SFC), a component can reference itself in its own template using its filename as the component name. This is useful for recursive components like tree structures or nested comments. However, this implicit registration has lower priority than explicitly imported components, which can cause confusion.
12
+
13
+ ## Task Checklist
14
+
15
+ - [ ] Use the filename (without extension) to self-reference a component
16
+ - [ ] Be aware that imported components take precedence over self-reference
17
+ - [ ] For clarity in recursive components, consider explicit naming
18
+
19
+ **Example:**
20
+ ```vue
21
+ <!-- TreeItem.vue -->
22
+ <script setup>
23
+ defineProps({
24
+ item: Object
25
+ })
26
+ </script>
27
+
28
+ <template>
29
+ <div class="tree-item">
30
+ <span>{{ item.name }}</span>
31
+ <!-- Self-reference using filename -->
32
+ <TreeItem
33
+ v-for="child in item.children"
34
+ :key="child.id"
35
+ :item="child"
36
+ />
37
+ </div>
38
+ </template>
39
+ ```
40
+
41
+ ```vue
42
+ <!-- Comment.vue - recursive comments -->
43
+ <script setup>
44
+ defineProps({
45
+ comment: Object
46
+ })
47
+ </script>
48
+
49
+ <template>
50
+ <div class="comment">
51
+ <p>{{ comment.text }}</p>
52
+ <div class="replies" v-if="comment.replies?.length">
53
+ <!-- Self-reference for nested replies -->
54
+ <Comment
55
+ v-for="reply in comment.replies"
56
+ :key="reply.id"
57
+ :comment="reply"
58
+ />
59
+ </div>
60
+ </div>
61
+ </template>
62
+ ```
63
+
64
+ ## Priority: Imports Override Self-Reference
65
+
66
+ ```vue
67
+ <!-- FooBar.vue -->
68
+ <script setup>
69
+ // If you import a component named FooBar, it takes precedence
70
+ import FooBar from './different/FooBar.vue'
71
+ </script>
72
+
73
+ <template>
74
+ <!-- This renders the IMPORTED FooBar, not this file -->
75
+ <FooBar />
76
+ </template>
77
+ ```
78
+
79
+ To explicitly self-reference when there's a naming conflict:
80
+
81
+ ```vue
82
+ <!-- FooBar.vue -->
83
+ <script setup>
84
+ import OtherFooBar from './different/FooBar.vue'
85
+ // No way to explicitly import "self" in script setup
86
+ // Must rename the import to avoid conflict
87
+ </script>
88
+
89
+ <template>
90
+ <OtherFooBar />
91
+ <!-- FooBar still refers to self (this file) because
92
+ the import was aliased -->
93
+ <FooBar />
94
+ </template>
95
+ ```
96
+
97
+ ## Options API: Explicit Name Option
98
+
99
+ ```vue
100
+ <!-- RecursiveList.vue -->
101
+ <script>
102
+ export default {
103
+ name: 'RecursiveList', // Explicit name for self-reference
104
+ props: {
105
+ items: Array
106
+ }
107
+ }
108
+ </script>
109
+
110
+ <template>
111
+ <ul>
112
+ <li v-for="item in items" :key="item.id">
113
+ {{ item.name }}
114
+ <RecursiveList v-if="item.children" :items="item.children" />
115
+ </li>
116
+ </ul>
117
+ </template>
118
+ ```
119
+
120
+ ## Common Use Cases for Self-Reference
121
+
122
+ 1. **Tree structures** - File explorers, org charts
123
+ 2. **Nested comments** - Reddit-style comment threads
124
+ 3. **Menu navigation** - Recursive dropdown menus
125
+ 4. **Category hierarchies** - Product categories, taxonomies
126
+
127
+ ## Avoid Infinite Recursion
128
+
129
+ ```vue
130
+ <!-- TreeNode.vue -->
131
+ <script setup>
132
+ defineProps({
133
+ node: Object,
134
+ maxDepth: { type: Number, default: 10 },
135
+ currentDepth: { type: Number, default: 0 }
136
+ })
137
+ </script>
138
+
139
+ <template>
140
+ <div class="node">
141
+ {{ node.name }}
142
+ <!-- Guard against infinite recursion -->
143
+ <template v-if="node.children && currentDepth < maxDepth">
144
+ <TreeNode
145
+ v-for="child in node.children"
146
+ :key="child.id"
147
+ :node="child"
148
+ :max-depth="maxDepth"
149
+ :current-depth="currentDepth + 1"
150
+ />
151
+ </template>
152
+ </div>
153
+ </template>
154
+ ```
155
+
156
+ ## Reference
157
+ - [Vue.js Component Registration](https://vuejs.org/guide/components/registration.html)
@@ -0,0 +1,184 @@
1
+ ---
2
+ title: SFC Script Block Must Use Default Export Only
3
+ impact: HIGH
4
+ impactDescription: Named exports in SFC script blocks will fail silently or cause build errors - Vue expects exactly one default export
5
+ type: gotcha
6
+ tags: [vue3, sfc, export, script-block, composition-api]
7
+ ---
8
+
9
+ # SFC Script Block Must Use Default Export Only
10
+
11
+ **Impact: HIGH** - Vue Single-File Components expect exactly one default export from the `<script>` block. Using named exports for your component will cause build failures or runtime errors because Vue's tooling is designed to process a single default-exported component definition per `.vue` file.
12
+
13
+ ## Task Checklist
14
+
15
+ - [ ] Always use `export default` in `<script>` blocks (Options API)
16
+ - [ ] Use `<script setup>` which handles exports automatically (Composition API)
17
+ - [ ] Move shared utilities to separate `.js`/`.ts` files, not the component's script block
18
+ - [ ] If you need to export types, use a separate `<script>` block alongside `<script setup>`
19
+
20
+ **Problematic Code:**
21
+ ```vue
22
+ <!-- MyComponent.vue -->
23
+ <script>
24
+ // BAD: Named exports don't work for the component itself
25
+ export const MyComponent = {
26
+ data() {
27
+ return { count: 0 }
28
+ }
29
+ }
30
+
31
+ // BAD: Exporting multiple things from component script
32
+ export const CONSTANT = 42
33
+ export function helper() { }
34
+ </script>
35
+
36
+ <template>
37
+ <div>{{ count }}</div>
38
+ </template>
39
+ ```
40
+
41
+ **Correct Code:**
42
+ ```vue
43
+ <!-- MyComponent.vue - Options API -->
44
+ <script>
45
+ // GOOD: Single default export
46
+ export default {
47
+ data() {
48
+ return { count: 0 }
49
+ }
50
+ }
51
+ </script>
52
+
53
+ <template>
54
+ <div>{{ count }}</div>
55
+ </template>
56
+ ```
57
+
58
+ ```vue
59
+ <!-- MyComponent.vue - Composition API with script setup -->
60
+ <script setup>
61
+ // GOOD: No export needed, component is auto-exported
62
+ import { ref } from 'vue'
63
+
64
+ const count = ref(0)
65
+ </script>
66
+
67
+ <template>
68
+ <div>{{ count }}</div>
69
+ </template>
70
+ ```
71
+
72
+ ## Exporting Types Alongside Script Setup
73
+
74
+ For TypeScript, use a separate regular script block for type exports:
75
+
76
+ ```vue
77
+ <script lang="ts">
78
+ // Regular script block for exports
79
+ export interface User {
80
+ id: number
81
+ name: string
82
+ }
83
+
84
+ export type Status = 'pending' | 'active' | 'inactive'
85
+ </script>
86
+
87
+ <script setup lang="ts">
88
+ // Setup script for component logic
89
+ import { ref } from 'vue'
90
+
91
+ const users = ref<User[]>([])
92
+ </script>
93
+
94
+ <template>
95
+ <ul>
96
+ <li v-for="user in users" :key="user.id">{{ user.name }}</li>
97
+ </ul>
98
+ </template>
99
+ ```
100
+
101
+ ## Sharing Utilities Across Components
102
+
103
+ Don't put shared code in component script blocks. Create separate files:
104
+
105
+ ```typescript
106
+ // utils/constants.ts
107
+ export const ITEMS_PER_PAGE = 20
108
+ export const API_BASE_URL = '/api/v1'
109
+
110
+ // utils/helpers.ts
111
+ export function formatDate(date: Date): string {
112
+ return date.toLocaleDateString()
113
+ }
114
+
115
+ export function formatCurrency(amount: number): string {
116
+ return `$${amount.toFixed(2)}`
117
+ }
118
+ ```
119
+
120
+ ```vue
121
+ <!-- ProductList.vue -->
122
+ <script setup>
123
+ // GOOD: Import shared utilities from external files
124
+ import { ITEMS_PER_PAGE } from '@/utils/constants'
125
+ import { formatCurrency } from '@/utils/helpers'
126
+ import { ref } from 'vue'
127
+
128
+ const products = ref([])
129
+ </script>
130
+ ```
131
+
132
+ ## Why This Restriction Exists
133
+
134
+ Vue's SFC compiler and build tools expect:
135
+
136
+ 1. **One component per file**: The `.vue` file format is designed for single-component definitions
137
+ 2. **Predictable structure**: Tools like Volar, vue-tsc, and bundler plugins assume default export
138
+ 3. **Hot Module Replacement**: HMR relies on the single-component-per-file convention
139
+
140
+ ```javascript
141
+ // How Vue tooling processes SFCs internally
142
+ import MyComponent from './MyComponent.vue'
143
+ // ^ Always expects the default export to be the component
144
+ ```
145
+
146
+ ## Common Mistake: Reusing Code via SFC Exports
147
+
148
+ ```vue
149
+ <!-- BAD PATTERN: Trying to reuse code from components -->
150
+ <script>
151
+ // This won't work as expected
152
+ export const sharedLogic = () => { ... }
153
+
154
+ export default {
155
+ // component definition
156
+ }
157
+ </script>
158
+ ```
159
+
160
+ Instead, use composables:
161
+
162
+ ```typescript
163
+ // composables/useSharedLogic.ts
164
+ export function useSharedLogic() {
165
+ // Shared reactive logic
166
+ const state = ref(0)
167
+ const increment = () => state.value++
168
+
169
+ return { state, increment }
170
+ }
171
+ ```
172
+
173
+ ```vue
174
+ <!-- ComponentA.vue -->
175
+ <script setup>
176
+ import { useSharedLogic } from '@/composables/useSharedLogic'
177
+
178
+ const { state, increment } = useSharedLogic()
179
+ </script>
180
+ ```
181
+
182
+ ## Reference
183
+ - [Vue.js SFC Specification](https://vuejs.org/api/sfc-spec.html)
184
+ - [Vue.js Composition API - Composables](https://vuejs.org/guide/reusability/composables.html)
@@ -0,0 +1,156 @@
1
+ ---
2
+ title: Use Deep Selectors for Styling Child Component Elements
3
+ impact: HIGH
4
+ impactDescription: Scoped styles cannot target elements inside child components without deep selectors, leading to silently broken styles
5
+ type: gotcha
6
+ tags: [vue3, sfc, scoped-css, deep-selector, child-components]
7
+ ---
8
+
9
+ # Use Deep Selectors for Styling Child Component Elements
10
+
11
+ **Impact: HIGH** - When using scoped CSS in Vue SFCs, styles do not penetrate into child components. Without using deep selectors (`:deep()`), your styles will silently fail to apply to elements rendered by child components or third-party libraries.
12
+
13
+ ## Task Checklist
14
+
15
+ - [ ] Use `:deep()` selector to style elements inside child components
16
+ - [ ] Never use deprecated `>>>` or `/deep/` selectors (Vue 3 only supports `:deep()`)
17
+ - [ ] Scope deep selectors to a parent class when possible to limit impact
18
+ - [ ] Consider using unscoped styles or CSS modules for heavily nested styling
19
+
20
+ **Problematic Code:**
21
+ ```vue
22
+ <template>
23
+ <div class="container">
24
+ <ThirdPartyDatePicker />
25
+ </div>
26
+ </template>
27
+
28
+ <style scoped>
29
+ /* BAD: These styles won't apply to elements inside ThirdPartyDatePicker */
30
+ .container .date-input {
31
+ border-color: blue;
32
+ }
33
+
34
+ .container .calendar-popup {
35
+ background: white;
36
+ }
37
+ </style>
38
+ ```
39
+
40
+ **Correct Code:**
41
+ ```vue
42
+ <template>
43
+ <div class="container">
44
+ <ThirdPartyDatePicker />
45
+ </div>
46
+ </template>
47
+
48
+ <style scoped>
49
+ /* GOOD: Use :deep() to style child component elements */
50
+ .container :deep(.date-input) {
51
+ border-color: blue;
52
+ }
53
+
54
+ .container :deep(.calendar-popup) {
55
+ background: white;
56
+ }
57
+
58
+ /* Also correct: deep selector at root level */
59
+ :deep(.date-picker-wrapper) {
60
+ padding: 1rem;
61
+ }
62
+ </style>
63
+ ```
64
+
65
+ ## How Scoped CSS Works
66
+
67
+ Vue scoped CSS adds a unique data attribute to all elements in the component's template and appends it to CSS selectors:
68
+
69
+ ```vue
70
+ <!-- Template output -->
71
+ <div class="container" data-v-7ba5bd90>
72
+ <!-- Child component elements DON'T get data-v-7ba5bd90 -->
73
+ <div class="date-input">...</div>
74
+ </div>
75
+ ```
76
+
77
+ ```css
78
+ /* Generated scoped CSS */
79
+ .container[data-v-7ba5bd90] .date-input[data-v-7ba5bd90] { ... }
80
+ /* ^ This won't match because .date-input doesn't have the attribute */
81
+ ```
82
+
83
+ ## Vue 3 Deep Selector Syntax
84
+
85
+ ```vue
86
+ <style scoped>
87
+ /* Vue 3 recommended syntax */
88
+ .parent :deep(.child-class) {
89
+ color: red;
90
+ }
91
+
92
+ /* DEPRECATED - don't use these in Vue 3 */
93
+ .parent >>> .child-class { } /* Won't work in SCSS */
94
+ .parent /deep/ .child-class { } /* Deprecated */
95
+ .parent ::v-deep .child-class { } /* Old syntax */
96
+ </style>
97
+ ```
98
+
99
+ ## Scoping Deep Selectors for Safety
100
+
101
+ Always scope `:deep()` to a parent selector to limit its reach:
102
+
103
+ ```vue
104
+ <style scoped>
105
+ /* BAD: Affects ALL .btn elements in child components globally */
106
+ :deep(.btn) {
107
+ background: blue;
108
+ }
109
+
110
+ /* GOOD: Only affects .btn inside .my-component */
111
+ .my-component :deep(.btn) {
112
+ background: blue;
113
+ }
114
+ </style>
115
+ ```
116
+
117
+ ## Child Component Root Element Exception
118
+
119
+ Note: A child component's root element IS affected by parent scoped CSS. This is intentional for layout purposes:
120
+
121
+ ```vue
122
+ <!-- Parent.vue -->
123
+ <template>
124
+ <ChildComponent class="styled-child" />
125
+ </template>
126
+
127
+ <style scoped>
128
+ /* This WILL work - targets child's root element */
129
+ .styled-child {
130
+ margin: 1rem;
131
+ border: 1px solid gray;
132
+ }
133
+ </style>
134
+ ```
135
+
136
+ ## Performance Consideration
137
+
138
+ Using `:deep()` with element selectors can be slower:
139
+
140
+ ```vue
141
+ <style scoped>
142
+ /* SLOWER: Element selector with deep */
143
+ .container :deep(p) {
144
+ color: red;
145
+ }
146
+
147
+ /* FASTER: Class selector with deep */
148
+ .container :deep(.paragraph) {
149
+ color: red;
150
+ }
151
+ </style>
152
+ ```
153
+
154
+ ## Reference
155
+ - [Vue.js Scoped CSS - Deep Selectors](https://vuejs.org/api/sfc-css-features.html#deep-selectors)
156
+ - [Vue Loader Scoped CSS](https://vue-loader.vuejs.org/guide/scoped-css.html)