mdk-skills 2.2.0 → 2.2.2

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 (191) hide show
  1. package/.claude/.install.log +31 -0
  2. package/.claude/backups/20260510.145547/.install.log +18 -0
  3. package/.claude/backups/20260510.145547/skills/test1/.meta.json +6 -0
  4. package/.claude/backups/20260510.145547/skills/test2/.meta.json +6 -0
  5. package/.claude/backups/20260510.145651/.install.log +19 -0
  6. package/.claude/backups/20260510.145651/profiles.json +67 -0
  7. package/.claude/backups/20260510.145651/settings.json +29 -0
  8. package/.claude/backups/20260510.145651/skills/frontend-code-review/.meta.json +6 -0
  9. package/.claude/backups/20260510.145651/skills/frontend-code-review/SKILL.md +167 -0
  10. package/.claude/backups/20260510.145651/skills/frontend-code-review/references/checklist.md +298 -0
  11. package/.claude/backups/20260510.145651/skills/frontend-design/.meta.json +6 -0
  12. package/.claude/backups/20260510.145651/skills/frontend-design/LICENSE.txt +177 -0
  13. package/.claude/backups/20260510.145651/skills/frontend-design/SKILL.md +42 -0
  14. package/.claude/backups/20260510.145651/skills/skill-creator/.meta.json +6 -0
  15. package/.claude/backups/20260510.145651/skills/skill-creator/SKILL.md +356 -0
  16. package/.claude/backups/20260510.145651/skills/skill-creator/references/output-patterns.md +82 -0
  17. package/.claude/backups/20260510.145651/skills/skill-creator/references/workflows.md +28 -0
  18. package/.claude/backups/20260510.145651/skills/skill-creator/scripts/init_skill.py +303 -0
  19. package/.claude/backups/20260510.145651/skills/skill-creator/scripts/package_skill.py +110 -0
  20. package/.claude/backups/20260510.145651/skills/skill-creator/scripts/quick_validate.py +95 -0
  21. package/.claude/backups/20260510.145651/skills/test1/.meta.json +6 -0
  22. package/.claude/backups/20260510.145651/skills/test2/.meta.json +6 -0
  23. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/.meta.json +6 -0
  24. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/SKILL.md +228 -0
  25. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/charts.csv +26 -0
  26. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/colors.csv +97 -0
  27. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/landing.csv +31 -0
  28. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/products.csv +97 -0
  29. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/prompts.csv +24 -0
  30. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  31. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  32. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  33. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  34. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  35. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  36. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  37. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  38. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  39. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  40. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/styles.csv +59 -0
  41. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/typography.csv +58 -0
  42. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  43. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/scripts/core.py +238 -0
  44. package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/scripts/search.py +61 -0
  45. package/.claude/backups/20260510.145651/skills/v3-fe-biz-patterns/.meta.json +6 -0
  46. package/.claude/backups/20260510.145651/skills/v3-fe-biz-patterns/SKILL.md +26 -0
  47. package/.claude/backups/20260510.145651/skills/v3-fe-biz-patterns/references/infinite-scroll.md +292 -0
  48. package/.claude/backups/20260510.145651/skills/v3-fe-biz-patterns/references/pinia-store.md +174 -0
  49. package/.claude/backups/20260510.145651/skills/v3-fe-biz-patterns/references/service-layer.md +198 -0
  50. package/.claude/backups/20260510.145651/skills/v3-fe-biz-patterns/references/tab-anchor.md +1125 -0
  51. package/.claude/backups/20260510.145651/skills/v3-fe-biz-patterns/references/use-loading.md +114 -0
  52. package/.claude/backups/20260510.145651/skills/vue/.meta.json +6 -0
  53. package/.claude/backups/20260510.145651/skills/vue/SKILL.md +103 -0
  54. package/.claude/backups/20260510.145651/skills/vue/references/components.md +323 -0
  55. package/.claude/backups/20260510.145651/skills/vue/references/composables.md +358 -0
  56. package/.claude/backups/20260510.145651/skills/vue/references/directives.md +225 -0
  57. package/.claude/backups/20260510.145651/skills/vue/references/gotchas.md +438 -0
  58. package/.claude/backups/20260510.145651/skills/vue/references/provide-inject.md +174 -0
  59. package/.claude/backups/20260510.145651/skills/vue/references/reactivity.md +289 -0
  60. package/.claude/backups/20260510.145651/skills/vue/references/router.md +181 -0
  61. package/.claude/backups/20260510.145651/skills/vue/references/testing.md +294 -0
  62. package/.claude/backups/20260510.145651/skills/vue/references/typescript.md +172 -0
  63. package/.claude/backups/20260510.145651/skills/vue/references/utils-client.md +156 -0
  64. package/.claude/backups/20260510.150310/.install.log +30 -0
  65. package/.claude/backups/20260510.150310/profiles.json +67 -0
  66. package/.claude/backups/20260510.150310/settings.json +29 -0
  67. package/.claude/backups/20260510.150310/skills/frontend-code-review/.meta.json +6 -0
  68. package/.claude/backups/20260510.150310/skills/frontend-code-review/SKILL.md +167 -0
  69. package/.claude/backups/20260510.150310/skills/frontend-code-review/references/checklist.md +298 -0
  70. package/.claude/backups/20260510.150310/skills/frontend-design/.meta.json +6 -0
  71. package/.claude/backups/20260510.150310/skills/frontend-design/LICENSE.txt +177 -0
  72. package/.claude/backups/20260510.150310/skills/frontend-design/SKILL.md +42 -0
  73. package/.claude/backups/20260510.150310/skills/skill-creator/.meta.json +6 -0
  74. package/.claude/backups/20260510.150310/skills/skill-creator/SKILL.md +356 -0
  75. package/.claude/backups/20260510.150310/skills/skill-creator/references/output-patterns.md +82 -0
  76. package/.claude/backups/20260510.150310/skills/skill-creator/references/workflows.md +28 -0
  77. package/.claude/backups/20260510.150310/skills/skill-creator/scripts/init_skill.py +303 -0
  78. package/.claude/backups/20260510.150310/skills/skill-creator/scripts/package_skill.py +110 -0
  79. package/.claude/backups/20260510.150310/skills/skill-creator/scripts/quick_validate.py +95 -0
  80. package/.claude/backups/20260510.150310/skills/test1/.meta.json +6 -0
  81. package/.claude/backups/20260510.150310/skills/test2/.meta.json +6 -0
  82. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/.meta.json +6 -0
  83. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/SKILL.md +228 -0
  84. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/charts.csv +26 -0
  85. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/colors.csv +97 -0
  86. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/landing.csv +31 -0
  87. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/products.csv +97 -0
  88. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/prompts.csv +24 -0
  89. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  90. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  91. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  92. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  93. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  94. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  95. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  96. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  97. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  98. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  99. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/styles.csv +59 -0
  100. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/typography.csv +58 -0
  101. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  102. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/scripts/core.py +238 -0
  103. package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/scripts/search.py +61 -0
  104. package/.claude/backups/20260510.150310/skills/v3-fe-biz-patterns/.meta.json +6 -0
  105. package/.claude/backups/20260510.150310/skills/v3-fe-biz-patterns/SKILL.md +26 -0
  106. package/.claude/backups/20260510.150310/skills/v3-fe-biz-patterns/references/infinite-scroll.md +292 -0
  107. package/.claude/backups/20260510.150310/skills/v3-fe-biz-patterns/references/pinia-store.md +174 -0
  108. package/.claude/backups/20260510.150310/skills/v3-fe-biz-patterns/references/service-layer.md +198 -0
  109. package/.claude/backups/20260510.150310/skills/v3-fe-biz-patterns/references/tab-anchor.md +1125 -0
  110. package/.claude/backups/20260510.150310/skills/v3-fe-biz-patterns/references/use-loading.md +114 -0
  111. package/.claude/backups/20260510.150310/skills/vue/.meta.json +6 -0
  112. package/.claude/backups/20260510.150310/skills/vue/SKILL.md +103 -0
  113. package/.claude/backups/20260510.150310/skills/vue/references/components.md +323 -0
  114. package/.claude/backups/20260510.150310/skills/vue/references/composables.md +358 -0
  115. package/.claude/backups/20260510.150310/skills/vue/references/directives.md +225 -0
  116. package/.claude/backups/20260510.150310/skills/vue/references/gotchas.md +438 -0
  117. package/.claude/backups/20260510.150310/skills/vue/references/provide-inject.md +174 -0
  118. package/.claude/backups/20260510.150310/skills/vue/references/reactivity.md +289 -0
  119. package/.claude/backups/20260510.150310/skills/vue/references/router.md +181 -0
  120. package/.claude/backups/20260510.150310/skills/vue/references/testing.md +294 -0
  121. package/.claude/backups/20260510.150310/skills/vue/references/typescript.md +172 -0
  122. package/.claude/backups/20260510.150310/skills/vue/references/utils-client.md +156 -0
  123. package/.claude/backups/CLAUDE.md.20260510.145155 +131 -0
  124. package/.claude/backups/CLAUDE.md.20260510.145651 +131 -0
  125. package/.claude/backups/CLAUDE.md.20260510.150310 +131 -0
  126. package/.claude/settings.json +1 -7
  127. package/.claude/skills/test1/.meta.json +6 -0
  128. package/.claude/skills/test2/.meta.json +6 -0
  129. package/package.json +1 -1
  130. package/scripts/cli.js +1 -1
  131. package/scripts/web-ui/server.js +2 -1
  132. package/scripts/web-ui/src/App.vue +1 -2
  133. package/scripts/web-ui/src/api/skills.js +5 -1
  134. package/scripts/web-ui/src/views/Dashboard.vue +12 -1
  135. package/.claude/backups/20260510.144501/.install.log +0 -1
  136. /package/.claude/backups/{20260510.144501 → 20260510.145547}/profiles.json +0 -0
  137. /package/.claude/backups/{20260510.144501 → 20260510.145547}/settings.json +0 -0
  138. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/frontend-code-review/.meta.json +0 -0
  139. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/frontend-code-review/SKILL.md +0 -0
  140. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/frontend-code-review/references/checklist.md +0 -0
  141. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/frontend-design/.meta.json +0 -0
  142. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/frontend-design/LICENSE.txt +0 -0
  143. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/frontend-design/SKILL.md +0 -0
  144. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/skill-creator/.meta.json +0 -0
  145. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/skill-creator/SKILL.md +0 -0
  146. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/skill-creator/references/output-patterns.md +0 -0
  147. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/skill-creator/references/workflows.md +0 -0
  148. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/skill-creator/scripts/init_skill.py +0 -0
  149. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/skill-creator/scripts/package_skill.py +0 -0
  150. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/skill-creator/scripts/quick_validate.py +0 -0
  151. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/.meta.json +0 -0
  152. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/SKILL.md +0 -0
  153. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/data/charts.csv +0 -0
  154. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/data/colors.csv +0 -0
  155. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/data/landing.csv +0 -0
  156. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/data/products.csv +0 -0
  157. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/data/prompts.csv +0 -0
  158. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/data/stacks/flutter.csv +0 -0
  159. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +0 -0
  160. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/data/stacks/nextjs.csv +0 -0
  161. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +0 -0
  162. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +0 -0
  163. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/data/stacks/react-native.csv +0 -0
  164. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/data/stacks/react.csv +0 -0
  165. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/data/stacks/svelte.csv +0 -0
  166. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/data/stacks/swiftui.csv +0 -0
  167. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/data/stacks/vue.csv +0 -0
  168. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/data/styles.csv +0 -0
  169. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/data/typography.csv +0 -0
  170. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/data/ux-guidelines.csv +0 -0
  171. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/scripts/core.py +0 -0
  172. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/ui-ux-pro-max/scripts/search.py +0 -0
  173. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/v3-fe-biz-patterns/.meta.json +0 -0
  174. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/v3-fe-biz-patterns/SKILL.md +0 -0
  175. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/v3-fe-biz-patterns/references/infinite-scroll.md +0 -0
  176. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/v3-fe-biz-patterns/references/pinia-store.md +0 -0
  177. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/v3-fe-biz-patterns/references/service-layer.md +0 -0
  178. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/v3-fe-biz-patterns/references/tab-anchor.md +0 -0
  179. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/v3-fe-biz-patterns/references/use-loading.md +0 -0
  180. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/vue/.meta.json +0 -0
  181. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/vue/SKILL.md +0 -0
  182. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/vue/references/components.md +0 -0
  183. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/vue/references/composables.md +0 -0
  184. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/vue/references/directives.md +0 -0
  185. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/vue/references/gotchas.md +0 -0
  186. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/vue/references/provide-inject.md +0 -0
  187. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/vue/references/reactivity.md +0 -0
  188. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/vue/references/router.md +0 -0
  189. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/vue/references/testing.md +0 -0
  190. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/vue/references/typescript.md +0 -0
  191. /package/.claude/backups/{20260510.144501 → 20260510.145547}/skills/vue/references/utils-client.md +0 -0
@@ -0,0 +1,114 @@
1
+ # 通用 Loading 管理方案
2
+
3
+ ## 概述
4
+
5
+ 异步操作的 loading 状态管理是前端最基础的需求之一。`useLoading` 是一个极简的通用 loading 包装器,用最小的代码量解决 loading 状态控制问题。
6
+
7
+ ## 源码
8
+
9
+ ```ts
10
+ // src/hooks/useLoading.ts
11
+ import { ref } from 'vue'
12
+
13
+ export function useLoading(initial = false) {
14
+ const loading = ref(initial)
15
+
16
+ async function withLoading<T>(fn: () => Promise<T>): Promise<T> {
17
+ loading.value = true
18
+ try {
19
+ return await fn()
20
+ } finally {
21
+ loading.value = false
22
+ }
23
+ }
24
+
25
+ return { loading, withLoading }
26
+ }
27
+ ```
28
+
29
+ 核心逻辑只有一行:执行前设 `true`,finally 中设回 `false`,保证无论成功还是失败 loading 都能复位。
30
+
31
+ ## 使用示例
32
+
33
+ ### 表单提交
34
+
35
+ ```vue
36
+ <script setup lang="ts">
37
+ const { loading, withLoading } = useLoading()
38
+
39
+ const onSubmit = async () => {
40
+ await withLoading(() => updateUser(form.value))
41
+ }
42
+ </script>
43
+
44
+ <template>
45
+ <van-button :loading="loading" @click="onSubmit">提交</van-button>
46
+ </template>
47
+ ```
48
+
49
+ ### 初始数据加载
50
+
51
+ ```vue
52
+ <script setup lang="ts">
53
+ const { loading, withLoading } = useLoading(true) // 初始就为 true
54
+
55
+ onMounted(() => {
56
+ withLoading(async () => {
57
+ await fetchUserInfo()
58
+ await fetchPermissions()
59
+ })
60
+ })
61
+ </script>
62
+
63
+ <template>
64
+ <BaseLoading :loading="loading" type="spinner" text="正在加载..." vertical />
65
+ <template v-if="!loading">
66
+ <!-- 主体内容 -->
67
+ </template>
68
+ </template>
69
+ ```
70
+
71
+ ### 多个独立 loading(初始加载 + 加载更多)
72
+
73
+ ```vue
74
+ <script setup lang="ts">
75
+ // 首次加载
76
+ const { loading: initLoading, withLoading: withInitLoading } = useLoading()
77
+ // 加载更多
78
+ const { loading: moreLoading, withLoading: withMoreLoading } = useLoading()
79
+
80
+ const onLoadMore = () => {
81
+ withMoreLoading(() => fetchHouseList(page + 1))
82
+ }
83
+
84
+ onMounted(() => {
85
+ withInitLoading(async () => {
86
+ await fetchHotSuggests()
87
+ await fetchCategories()
88
+ await fetchHouseList()
89
+ })
90
+ })
91
+ </script>
92
+
93
+ <template>
94
+ <!-- 首次加载用全屏 loading -->
95
+ <BaseLoading :loading="initLoading" type="spinner" vertical />
96
+ <!-- 加载更多只影响底部 -->
97
+ <div v-if="moreLoading">加载更多...</div>
98
+ </template>
99
+ ```
100
+
101
+ ## 常见问题
102
+
103
+ | 场景 | 处理方式 |
104
+ |------|---------|
105
+ | 重复点击提交 | `loading` 为 true 时按钮置灰 / `:loading` 属性,无需额外逻辑 |
106
+ | 多个请求并行 | 需要分别管理 loading 时创建多个 `useLoading` 实例 |
107
+ | 组件卸载 | 不影响,`withLoading` 的 finally 中赋值不会有问题(Vue 会处理) |
108
+ | 需要 loading 之外的状态 | 搭配 `error`、`data` 等额外 ref 使用,`useLoading` 只负责 loading |
109
+
110
+ ## 注意事项
111
+
112
+ 1. **不要滥用**:简单的 Boolean 控制直接写模板里就行,不需要每个异步操作都抽成一个 hook
113
+ 2. **区分 loading 粒度**:页面级 loading 用一个实例,列表加载更多用另一个实例,互不干扰
114
+ 3. **`withLoading` 的返回值**:它返回的是 `fn()` 的 Promise 结果,可以用它链式处理后续逻辑
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "vue",
3
+ "version": "1.0.0",
4
+ "description": "Vue 3 组件/组合式函数开发,Composition API 最佳实践",
5
+ "tags": ["vue", "frontend", "composition-api"]
6
+ }
@@ -0,0 +1,103 @@
1
+ ---
2
+ name: vue
3
+ description: Use when editing .vue files, creating Vue 3 components, writing composables, or testing Vue code - provides Composition API patterns, props/emits best practices, VueUse integration, and reactive destructuring guidance
4
+ license: MIT
5
+ ---
6
+
7
+ # Vue 3 Development
8
+
9
+ Reference for Vue 3 Composition API patterns, component architecture, and testing practices.
10
+
11
+ **Current stable:** Vue 3.5+ with enhanced reactivity performance (-56% memory, 10x faster array tracking), new SSR features, and improved developer experience.
12
+
13
+ ## Overview
14
+
15
+ Progressive reference system for Vue 3 projects. Load only files relevant to current task to minimize context usage (~250 tokens base, 500-1500 per sub-file).
16
+
17
+ ## When to Use
18
+
19
+ **Use this skill when:**
20
+
21
+ - Writing `.vue` components
22
+ - Creating composables (`use*` functions)
23
+ - Building client-side utilities
24
+ - Testing Vue components/composables
25
+
26
+ **Use `nuxt` skill instead for:**
27
+
28
+ - Server routes, API endpoints
29
+ - File-based routing, middleware
30
+ - Nuxt-specific patterns
31
+
32
+ **For styled UI components:** use `nuxt-ui` skill
33
+ **For headless accessible components:** use `reka-ui` skill
34
+ **For VueUse composables:** use `vueuse` skill
35
+
36
+ ## Quick Reference
37
+
38
+ | Working on... | Load file |
39
+ | ------------------------ | ---------------------------- |
40
+ | `.vue` in `components/` | references/components.md |
41
+ | File in `composables/` | references/composables.md |
42
+ | File in `utils/` | references/utils-client.md |
43
+ | `.spec.ts` or `.test.ts` | references/testing.md |
44
+ | TypeScript patterns | references/typescript.md |
45
+ | Vue Router typing | references/router.md |
46
+ | Reactivity (ref, watch) | references/reactivity.md |
47
+ | Custom directives | references/directives.md |
48
+ | Provide/inject | references/provide-inject.md |
49
+ | Edge cases, vue-tsc | references/gotchas.md |
50
+
51
+ ## Loading Files
52
+
53
+ **Consider loading these reference files based on your task:**
54
+
55
+ - [ ] [references/components.md](references/components.md) - if working in `components/` or writing `.vue` files
56
+ - [ ] [references/composables.md](references/composables.md) - if creating composables (`use*` functions)
57
+ - [ ] [references/utils-client.md](references/utils-client.md) - if working in `utils/` or writing client utilities
58
+ - [ ] [references/testing.md](references/testing.md) - if writing `.spec.ts` or `.test.ts` files
59
+ - [ ] [references/typescript.md](references/typescript.md) - if working with Vue TypeScript patterns or generics
60
+ - [ ] [references/router.md](references/router.md) - if working with Vue Router or route typing
61
+ - [ ] [references/reactivity.md](references/reactivity.md) - if using ref, reactive, computed, watch, or watchEffect
62
+ - [ ] [references/directives.md](references/directives.md) - if creating or using custom directives
63
+ - [ ] [references/provide-inject.md](references/provide-inject.md) - if using provide/inject patterns
64
+ - [ ] [references/gotchas.md](references/gotchas.md) - if debugging edge cases or hydration issues
65
+
66
+ **DO NOT load all files at once.** Load only what's relevant to your current task.
67
+
68
+ ## Quick Start
69
+
70
+ ```vue
71
+ <script setup lang="ts">
72
+ const { count = 0 } = defineProps<{ count?: number }>()
73
+ const emit = defineEmits<{ update: [value: number] }>()
74
+ </script>
75
+
76
+ <template>
77
+ <button @click="emit('update', count + 1)">
78
+ Count: {{ count }}
79
+ </button>
80
+ </template>
81
+ ```
82
+
83
+ ## Available Guidance
84
+
85
+ **[references/components.md](references/components.md)** - Props with reactive destructuring, emits patterns, defineModel for v-model, slots shorthand
86
+
87
+ **[references/composables.md](references/composables.md)** - Composition API structure, VueUse integration, lifecycle hooks, async patterns, reactivity gotchas
88
+
89
+ **[references/utils-client.md](references/utils-client.md)** - Pure functions, formatters, validators, transformers, when NOT to use utils
90
+
91
+ **[references/testing.md](references/testing.md)** - Vitest + @vue/test-utils, component testing, composable testing, router mocking
92
+
93
+ **[references/typescript.md](references/typescript.md)** - InjectionKey for provide/inject, vue-tsc strict templates, tsconfig settings, generic components
94
+
95
+ **[references/router.md](references/router.md)** - Route meta types, typed params with unplugin-vue-router, scroll behavior, navigation guards
96
+
97
+ **[references/reactivity.md](references/reactivity.md)** - ref, reactive, computed, watch, watchEffect, reactivity fundamentals
98
+
99
+ **[references/directives.md](references/directives.md)** - Custom directive hooks, v-focus, v-click-outside, v-tooltip patterns
100
+
101
+ **[references/provide-inject.md](references/provide-inject.md)** - InjectionKey typing, app-level provide, readonly patterns
102
+
103
+ **[references/gotchas.md](references/gotchas.md)** - Common gotchas, vue-tsc edge cases, hydration issues, race conditions (from vuejs-ai/skills)
@@ -0,0 +1,323 @@
1
+ # Vue Components
2
+
3
+ Patterns for Vue 3 components using Composition API with `<script setup>`.
4
+
5
+ ## Quick Reference
6
+
7
+ | Pattern | Syntax |
8
+ | --------------------- | --------------------------------------------------------------- |
9
+ | Props (destructured) | `const { name = 'default' } = defineProps<{ name?: string }>()` |
10
+ | Props (template-only) | `defineProps<{ name: string }>()` |
11
+ | Emits | `const emit = defineEmits<{ click: [id: number] }>()` |
12
+ | Two-way binding | `const model = defineModel<string>()` |
13
+ | Slots shorthand | `<template #header>` not `<template v-slot:header>` |
14
+
15
+ ## Naming
16
+
17
+ **Files:** PascalCase (`UserProfile.vue`) OR kebab-case (`user-profile.vue`) - be consistent
18
+
19
+ **Component names in code:** Always PascalCase
20
+
21
+ **Composition:** General → Specific: `SearchButtonClear.vue` not `ClearSearchButton.vue`
22
+
23
+ ## Props
24
+
25
+ **Destructure with defaults (Vue 3.5+)** when used in script or need defaults:
26
+
27
+ ```ts
28
+ const { count = 0, message = 'Hello' } = defineProps<{
29
+ count?: number
30
+ message?: string
31
+ required: boolean
32
+ }>()
33
+
34
+ // Use directly - maintains reactivity
35
+ console.log(count + 1)
36
+
37
+ // ⚠️ When passing to watchers/functions, wrap in getter:
38
+ watch(() => count, (newVal) => { ... }) // ✅ Correct
39
+ watch(count, (newVal) => { ... }) // ❌ Won't work
40
+ ```
41
+
42
+ **Non-destructured** only if props ONLY used in template:
43
+
44
+ ```ts
45
+ defineProps<{ count: number }>()
46
+ // Template: {{ count }}
47
+ ```
48
+
49
+ **Same-name shorthand (Vue 3.4+):** `:count` instead of `:count="count"`
50
+
51
+ ```vue
52
+ <MyComponent :count :user :items />
53
+ <!-- Same as: :count="count" :user="user" :items="items" -->
54
+ ```
55
+
56
+ [Reactive destructuring docs](https://vuejs.org/guide/components/props#reactive-props-destructure)
57
+
58
+ ## Emits
59
+
60
+ Type-safe event definitions:
61
+
62
+ ```ts
63
+ const emit = defineEmits<{
64
+ update: [id: number, value: string] // multiple args
65
+ close: [] // no args
66
+ }>()
67
+
68
+ // Usage
69
+ emit('update', 123, 'new value')
70
+ emit('close')
71
+ ```
72
+
73
+ **Template syntax:** kebab-case (`@update-item`) vs camelCase in script (`updateItem`)
74
+
75
+ ## Slots
76
+
77
+ **Always use shorthand:** `<template #header>` not `<template v-slot:header>`
78
+
79
+ **Always explicit `<template>` tags** for all slots
80
+
81
+ ```vue
82
+ <template>
83
+ <Card>
84
+ <template #header>
85
+ <h2>Title</h2>
86
+ </template>
87
+ <template #default>
88
+ Content
89
+ </template>
90
+ </Card>
91
+ </template>
92
+ ```
93
+
94
+ ## defineModel() - Two-Way Binding
95
+
96
+ Replaces manual `modelValue` prop + `update:modelValue` emit.
97
+
98
+ ### Basic
99
+
100
+ ```vue
101
+ <script setup lang="ts">
102
+ const title = defineModel<string>()
103
+ </script>
104
+
105
+ <template>
106
+ <input v-model="title">
107
+ </template>
108
+ ```
109
+
110
+ ### With Options
111
+
112
+ ```vue
113
+ <script setup lang="ts">
114
+ const [title, modifiers] = defineModel<string>({
115
+ default: 'default value',
116
+ required: true,
117
+ get: (value) => value.trim(),
118
+ set: (value) => {
119
+ if (modifiers.capitalize) {
120
+ return value.charAt(0).toUpperCase() + value.slice(1)
121
+ }
122
+ return value
123
+ },
124
+ })
125
+ </script>
126
+ ```
127
+
128
+ **⚠️ Warning:** When using `default` without parent providing a value, parent and child can de-sync (parent `undefined`, child has default). Always provide matching defaults in parent or make prop required.
129
+
130
+ **Prevent double-emit with `required: true`:**
131
+
132
+ ```ts
133
+ // ❌ Without required - emits twice (undefined then value)
134
+ const model = defineModel<Item>()
135
+
136
+ // ✅ With required - single emit
137
+ const model = defineModel<Item>({ required: true })
138
+ ```
139
+
140
+ Use `required: true` when the model should always have a value to avoid the double-emit issue during initialization.
141
+
142
+ ### Multiple Models
143
+
144
+ Default assumes `modelValue` prop. For multiple bindings, use explicit names:
145
+
146
+ ```vue
147
+ <script setup lang="ts">
148
+ const firstName = defineModel<string>('firstName')
149
+ const age = defineModel<number>('age')
150
+ </script>
151
+
152
+ <!-- Usage -->
153
+ <UserForm v-model:first-name="user.firstName" v-model:age="user.age" />
154
+ ```
155
+
156
+ [v-model modifiers docs](https://vuejs.org/guide/components/v-model#handling-v-model-modifiers)
157
+
158
+ ## Reusable Templates
159
+
160
+ For typed, scoped template snippets within a component:
161
+
162
+ ```vue
163
+ <script setup lang="ts">
164
+ import { createReusableTemplate } from '@vueuse/core'
165
+
166
+ const [DefineItem, UseItem] = createReusableTemplate<{
167
+ item: SearchItem
168
+ icon: string
169
+ color?: 'red' | 'green' | 'blue'
170
+ }>()
171
+ </script>
172
+
173
+ <template>
174
+ <DefineItem v-slot="{ item, icon, color }">
175
+ <div :class="color">
176
+ <Icon :name="icon" />
177
+ {{ item.name }}
178
+ </div>
179
+ </DefineItem>
180
+
181
+ <!-- Reuse multiple times -->
182
+ <UseItem v-for="item in items" :key="item.id" :item :icon="getIcon(item)" />
183
+ </template>
184
+ ```
185
+
186
+ ## Template Refs (Vue 3.5+)
187
+
188
+ Use `useTemplateRef()` for type-safe template references with IDE support:
189
+
190
+ ```vue
191
+ <script setup lang="ts">
192
+ import { useTemplateRef, onMounted } from 'vue'
193
+
194
+ const input = useTemplateRef<HTMLInputElement>('my-input')
195
+
196
+ onMounted(() => {
197
+ input.value?.focus()
198
+ })
199
+ </script>
200
+
201
+ <template>
202
+ <input ref="my-input">
203
+ </template>
204
+ ```
205
+
206
+ **Benefits over `ref()`:**
207
+
208
+ - Type-safe with generics
209
+ - Better IDE autocomplete and refactoring
210
+ - Explicit ref name as string literal
211
+
212
+ **Dynamic refs:**
213
+
214
+ ```vue
215
+ <script setup lang="ts">
216
+ const items = ref(['a', 'b', 'c'])
217
+ const itemRefs = useTemplateRef<HTMLElement>('item')
218
+
219
+ // Access refs after mount
220
+ onMounted(() => {
221
+ console.log(itemRefs.value) // Array of elements
222
+ })
223
+ </script>
224
+
225
+ <template>
226
+ <div v-for="item in items" :key="item" ref="item">
227
+ {{ item }}
228
+ </div>
229
+ </template>
230
+ ```
231
+
232
+ **Component refs with generics:**
233
+
234
+ For generic components, use `ComponentExposed` from `vue-component-type-helpers`:
235
+
236
+ ```ts
237
+ import type { ComponentExposed } from 'vue-component-type-helpers'
238
+ import MyGenericComponent from './MyGenericComponent.vue'
239
+
240
+ // Get exposed methods/properties with correct generic types
241
+ const compRef = useTemplateRef<ComponentExposed<typeof MyGenericComponent>>('comp')
242
+
243
+ onMounted(() => {
244
+ compRef.value?.someExposedMethod() // Typed!
245
+ })
246
+ ```
247
+
248
+ Install: `pnpm add -D vue-component-type-helpers`
249
+
250
+ ## SSR Hydration (Vue 3.5+)
251
+
252
+ **Suppress hydration mismatches** for values that differ between server/client:
253
+
254
+ ```vue
255
+ <template>
256
+ <!-- Client-side only values -->
257
+ <span data-allow-mismatch>{{ new Date().toLocaleString() }}</span>
258
+
259
+ <!-- Specific mismatch types -->
260
+ <span data-allow-mismatch="text">{{ timestamp }}</span>
261
+ <span data-allow-mismatch="children">
262
+ <ClientOnly>...</ClientOnly>
263
+ </span>
264
+ <span data-allow-mismatch="style">...</span>
265
+ <span data-allow-mismatch="class">...</span>
266
+ <span data-allow-mismatch="attribute">...</span>
267
+ </template>
268
+ ```
269
+
270
+ **Generate SSR-stable IDs:**
271
+
272
+ ```vue
273
+ <script setup lang="ts">
274
+ import { useId } from 'vue'
275
+
276
+ const id = useId() // Stable across server/client renders
277
+ </script>
278
+
279
+ <template>
280
+ <label :for="id">Name</label>
281
+ <input :id="id">
282
+ </template>
283
+ ```
284
+
285
+ ## Deferred Teleport (Vue 3.5+)
286
+
287
+ Teleport to elements rendered later in the same cycle:
288
+
289
+ ```vue
290
+ <template>
291
+ <!-- This renders first -->
292
+ <Teleport defer to="#late-div">
293
+ <span>Deferred content</span>
294
+ </Teleport>
295
+
296
+ <!-- This renders after, but Teleport waits -->
297
+ <div id="late-div"></div>
298
+ </template>
299
+ ```
300
+
301
+ Without `defer`, teleport to `#late-div` would fail since it doesn't exist yet.
302
+
303
+ ## Common Mistakes
304
+
305
+ **Using `const props =` with destructured values:**
306
+
307
+ ```ts
308
+ // ❌ Wrong
309
+ const props = defineProps<{ count: number }>()
310
+ const { count } = props // Loses reactivity
311
+ ```
312
+
313
+ **Forgetting TypeScript types:**
314
+
315
+ ```ts
316
+ // ❌ Wrong
317
+ const emit = defineEmits(['update'])
318
+
319
+ // ✅ Correct
320
+ const emit = defineEmits<{ update: [id: number] }>()
321
+ ```
322
+
323
+ **Components >300 lines:** Split into smaller components or extract logic to composables