mdk-skills 2.2.2 → 2.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/.install.log +9 -40
- package/.claude/backups/20260510.151953/.install.log +1 -0
- package/package.json +1 -1
- package/scripts/web-ui/server.js +8 -1
- package/.claude/backups/20260510.145547/.install.log +0 -18
- package/.claude/backups/20260510.145547/settings.json +0 -35
- package/.claude/backups/20260510.145547/skills/test1/.meta.json +0 -6
- package/.claude/backups/20260510.145547/skills/test2/.meta.json +0 -6
- package/.claude/backups/20260510.145651/.install.log +0 -19
- package/.claude/backups/20260510.145651/profiles.json +0 -67
- package/.claude/backups/20260510.145651/skills/frontend-code-review/.meta.json +0 -6
- package/.claude/backups/20260510.145651/skills/frontend-code-review/SKILL.md +0 -167
- package/.claude/backups/20260510.145651/skills/frontend-code-review/references/checklist.md +0 -298
- package/.claude/backups/20260510.145651/skills/frontend-design/.meta.json +0 -6
- package/.claude/backups/20260510.145651/skills/frontend-design/LICENSE.txt +0 -177
- package/.claude/backups/20260510.145651/skills/frontend-design/SKILL.md +0 -42
- package/.claude/backups/20260510.145651/skills/skill-creator/.meta.json +0 -6
- package/.claude/backups/20260510.145651/skills/skill-creator/SKILL.md +0 -356
- package/.claude/backups/20260510.145651/skills/skill-creator/references/output-patterns.md +0 -82
- package/.claude/backups/20260510.145651/skills/skill-creator/references/workflows.md +0 -28
- package/.claude/backups/20260510.145651/skills/skill-creator/scripts/init_skill.py +0 -303
- package/.claude/backups/20260510.145651/skills/skill-creator/scripts/package_skill.py +0 -110
- package/.claude/backups/20260510.145651/skills/skill-creator/scripts/quick_validate.py +0 -95
- package/.claude/backups/20260510.145651/skills/test1/.meta.json +0 -6
- package/.claude/backups/20260510.145651/skills/test2/.meta.json +0 -6
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/.meta.json +0 -6
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/SKILL.md +0 -228
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/charts.csv +0 -26
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/colors.csv +0 -97
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/landing.csv +0 -31
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/products.csv +0 -97
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/prompts.csv +0 -24
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/stacks/flutter.csv +0 -53
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +0 -56
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/stacks/nextjs.csv +0 -53
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +0 -51
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +0 -59
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/stacks/react-native.csv +0 -52
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/stacks/react.csv +0 -54
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/stacks/svelte.csv +0 -54
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/stacks/swiftui.csv +0 -51
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/stacks/vue.csv +0 -50
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/styles.csv +0 -59
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/typography.csv +0 -58
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/data/ux-guidelines.csv +0 -100
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/scripts/core.py +0 -238
- package/.claude/backups/20260510.145651/skills/ui-ux-pro-max/scripts/search.py +0 -61
- package/.claude/backups/20260510.145651/skills/v3-fe-biz-patterns/.meta.json +0 -6
- package/.claude/backups/20260510.145651/skills/v3-fe-biz-patterns/SKILL.md +0 -26
- package/.claude/backups/20260510.145651/skills/v3-fe-biz-patterns/references/infinite-scroll.md +0 -292
- package/.claude/backups/20260510.145651/skills/v3-fe-biz-patterns/references/pinia-store.md +0 -174
- package/.claude/backups/20260510.145651/skills/v3-fe-biz-patterns/references/service-layer.md +0 -198
- package/.claude/backups/20260510.145651/skills/v3-fe-biz-patterns/references/tab-anchor.md +0 -1125
- package/.claude/backups/20260510.145651/skills/v3-fe-biz-patterns/references/use-loading.md +0 -114
- package/.claude/backups/20260510.145651/skills/vue/.meta.json +0 -6
- package/.claude/backups/20260510.145651/skills/vue/SKILL.md +0 -103
- package/.claude/backups/20260510.145651/skills/vue/references/components.md +0 -323
- package/.claude/backups/20260510.145651/skills/vue/references/composables.md +0 -358
- package/.claude/backups/20260510.145651/skills/vue/references/directives.md +0 -225
- package/.claude/backups/20260510.145651/skills/vue/references/gotchas.md +0 -438
- package/.claude/backups/20260510.145651/skills/vue/references/provide-inject.md +0 -174
- package/.claude/backups/20260510.145651/skills/vue/references/reactivity.md +0 -289
- package/.claude/backups/20260510.145651/skills/vue/references/router.md +0 -181
- package/.claude/backups/20260510.145651/skills/vue/references/testing.md +0 -294
- package/.claude/backups/20260510.145651/skills/vue/references/typescript.md +0 -172
- package/.claude/backups/20260510.145651/skills/vue/references/utils-client.md +0 -156
- package/.claude/backups/20260510.150310/.install.log +0 -30
- package/.claude/backups/20260510.150310/profiles.json +0 -67
- package/.claude/backups/20260510.150310/settings.json +0 -29
- package/.claude/backups/20260510.150310/skills/frontend-code-review/.meta.json +0 -6
- package/.claude/backups/20260510.150310/skills/frontend-code-review/SKILL.md +0 -167
- package/.claude/backups/20260510.150310/skills/frontend-code-review/references/checklist.md +0 -298
- package/.claude/backups/20260510.150310/skills/frontend-design/.meta.json +0 -6
- package/.claude/backups/20260510.150310/skills/frontend-design/LICENSE.txt +0 -177
- package/.claude/backups/20260510.150310/skills/frontend-design/SKILL.md +0 -42
- package/.claude/backups/20260510.150310/skills/skill-creator/.meta.json +0 -6
- package/.claude/backups/20260510.150310/skills/skill-creator/SKILL.md +0 -356
- package/.claude/backups/20260510.150310/skills/skill-creator/references/output-patterns.md +0 -82
- package/.claude/backups/20260510.150310/skills/skill-creator/references/workflows.md +0 -28
- package/.claude/backups/20260510.150310/skills/skill-creator/scripts/init_skill.py +0 -303
- package/.claude/backups/20260510.150310/skills/skill-creator/scripts/package_skill.py +0 -110
- package/.claude/backups/20260510.150310/skills/skill-creator/scripts/quick_validate.py +0 -95
- package/.claude/backups/20260510.150310/skills/test1/.meta.json +0 -6
- package/.claude/backups/20260510.150310/skills/test2/.meta.json +0 -6
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/.meta.json +0 -6
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/SKILL.md +0 -228
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/charts.csv +0 -26
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/colors.csv +0 -97
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/landing.csv +0 -31
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/products.csv +0 -97
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/prompts.csv +0 -24
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/stacks/flutter.csv +0 -53
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +0 -56
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/stacks/nextjs.csv +0 -53
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +0 -51
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +0 -59
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/stacks/react-native.csv +0 -52
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/stacks/react.csv +0 -54
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/stacks/svelte.csv +0 -54
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/stacks/swiftui.csv +0 -51
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/stacks/vue.csv +0 -50
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/styles.csv +0 -59
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/typography.csv +0 -58
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/data/ux-guidelines.csv +0 -100
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/scripts/core.py +0 -238
- package/.claude/backups/20260510.150310/skills/ui-ux-pro-max/scripts/search.py +0 -61
- package/.claude/backups/20260510.150310/skills/v3-fe-biz-patterns/.meta.json +0 -6
- package/.claude/backups/20260510.150310/skills/v3-fe-biz-patterns/SKILL.md +0 -26
- package/.claude/backups/20260510.150310/skills/v3-fe-biz-patterns/references/infinite-scroll.md +0 -292
- package/.claude/backups/20260510.150310/skills/v3-fe-biz-patterns/references/pinia-store.md +0 -174
- package/.claude/backups/20260510.150310/skills/v3-fe-biz-patterns/references/service-layer.md +0 -198
- package/.claude/backups/20260510.150310/skills/v3-fe-biz-patterns/references/tab-anchor.md +0 -1125
- package/.claude/backups/20260510.150310/skills/v3-fe-biz-patterns/references/use-loading.md +0 -114
- package/.claude/backups/20260510.150310/skills/vue/.meta.json +0 -6
- package/.claude/backups/20260510.150310/skills/vue/SKILL.md +0 -103
- package/.claude/backups/20260510.150310/skills/vue/references/components.md +0 -323
- package/.claude/backups/20260510.150310/skills/vue/references/composables.md +0 -358
- package/.claude/backups/20260510.150310/skills/vue/references/directives.md +0 -225
- package/.claude/backups/20260510.150310/skills/vue/references/gotchas.md +0 -438
- package/.claude/backups/20260510.150310/skills/vue/references/provide-inject.md +0 -174
- package/.claude/backups/20260510.150310/skills/vue/references/reactivity.md +0 -289
- package/.claude/backups/20260510.150310/skills/vue/references/router.md +0 -181
- package/.claude/backups/20260510.150310/skills/vue/references/testing.md +0 -294
- package/.claude/backups/20260510.150310/skills/vue/references/typescript.md +0 -172
- package/.claude/backups/20260510.150310/skills/vue/references/utils-client.md +0 -156
- package/.claude/backups/CLAUDE.md.20260510.145155 +0 -131
- package/.claude/backups/CLAUDE.md.20260510.145651 +0 -131
- package/.claude/backups/CLAUDE.md.20260510.150310 +0 -131
- package/.claude/skills/test1/.meta.json +0 -6
- package/.claude/skills/test2/.meta.json +0 -6
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/profiles.json +0 -0
- /package/.claude/backups/{20260510.145651 → 20260510.151953}/settings.json +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/frontend-code-review/.meta.json +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/frontend-code-review/SKILL.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/frontend-code-review/references/checklist.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/frontend-design/.meta.json +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/frontend-design/LICENSE.txt +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/frontend-design/SKILL.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/skill-creator/.meta.json +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/skill-creator/SKILL.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/skill-creator/references/output-patterns.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/skill-creator/references/workflows.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/skill-creator/scripts/init_skill.py +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/skill-creator/scripts/package_skill.py +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/skill-creator/scripts/quick_validate.py +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/.meta.json +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/SKILL.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/data/charts.csv +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/data/colors.csv +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/data/landing.csv +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/data/products.csv +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/data/prompts.csv +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/data/stacks/flutter.csv +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/data/stacks/nextjs.csv +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/data/stacks/react-native.csv +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/data/stacks/react.csv +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/data/stacks/svelte.csv +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/data/stacks/swiftui.csv +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/data/stacks/vue.csv +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/data/styles.csv +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/data/typography.csv +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/data/ux-guidelines.csv +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/scripts/core.py +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/ui-ux-pro-max/scripts/search.py +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/v3-fe-biz-patterns/.meta.json +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/v3-fe-biz-patterns/SKILL.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/v3-fe-biz-patterns/references/infinite-scroll.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/v3-fe-biz-patterns/references/pinia-store.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/v3-fe-biz-patterns/references/service-layer.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/v3-fe-biz-patterns/references/tab-anchor.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/v3-fe-biz-patterns/references/use-loading.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/vue/.meta.json +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/vue/SKILL.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/vue/references/components.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/vue/references/composables.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/vue/references/directives.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/vue/references/gotchas.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/vue/references/provide-inject.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/vue/references/reactivity.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/vue/references/router.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/vue/references/testing.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/vue/references/typescript.md +0 -0
- /package/.claude/backups/{20260510.145547 → 20260510.151953}/skills/vue/references/utils-client.md +0 -0
- /package/.claude/backups/{CLAUDE.md.20260510.144501 → CLAUDE.md.20260510.151953} +0 -0
|
@@ -1,114 +0,0 @@
|
|
|
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 结果,可以用它链式处理后续逻辑
|
|
@@ -1,103 +0,0 @@
|
|
|
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)
|
|
@@ -1,323 +0,0 @@
|
|
|
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
|