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,289 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Vue Reactivity System
|
|
3
|
-
description: Core reactivity primitives - ref, reactive, computed, and watchers
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Vue Reactivity System
|
|
7
|
-
|
|
8
|
-
Vue's reactivity system enables automatic tracking of state changes and DOM updates.
|
|
9
|
-
|
|
10
|
-
## ref()
|
|
11
|
-
|
|
12
|
-
Create reactive primitive values with `ref()`. Access/modify via `.value` in JavaScript, auto-unwrapped in templates.
|
|
13
|
-
|
|
14
|
-
```ts
|
|
15
|
-
import { ref } from 'vue'
|
|
16
|
-
|
|
17
|
-
const count = ref(0)
|
|
18
|
-
console.log(count.value) // 0
|
|
19
|
-
count.value++
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
```vue
|
|
23
|
-
<script setup lang="ts">
|
|
24
|
-
import { ref } from 'vue'
|
|
25
|
-
|
|
26
|
-
const count = ref(0)
|
|
27
|
-
|
|
28
|
-
function increment() {
|
|
29
|
-
count.value++
|
|
30
|
-
}
|
|
31
|
-
</script>
|
|
32
|
-
|
|
33
|
-
<template>
|
|
34
|
-
<button @click="increment">{{ count }}</button>
|
|
35
|
-
</template>
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### Typing refs
|
|
39
|
-
|
|
40
|
-
```ts
|
|
41
|
-
import { ref } from 'vue'
|
|
42
|
-
import type { Ref } from 'vue'
|
|
43
|
-
|
|
44
|
-
// Type inference
|
|
45
|
-
const year = ref(2020) // Ref<number>
|
|
46
|
-
|
|
47
|
-
// Explicit generic
|
|
48
|
-
const name = ref<string | null>(null)
|
|
49
|
-
|
|
50
|
-
// Ref type annotation
|
|
51
|
-
const id: Ref<string | number> = ref('abc')
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
## reactive()
|
|
55
|
-
|
|
56
|
-
Create reactive objects. No `.value` needed, but cannot reassign the entire object.
|
|
57
|
-
|
|
58
|
-
```ts
|
|
59
|
-
import { reactive } from 'vue'
|
|
60
|
-
|
|
61
|
-
interface State {
|
|
62
|
-
count: number
|
|
63
|
-
name: string
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const state: State = reactive({
|
|
67
|
-
count: 0,
|
|
68
|
-
name: 'Vue'
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
state.count++ // reactive
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
### Limitations of reactive()
|
|
75
|
-
|
|
76
|
-
1. **Only works with objects** - not primitives
|
|
77
|
-
2. **Cannot replace entire object** - loses reactivity
|
|
78
|
-
3. **Destructuring loses reactivity** - use `toRefs()` instead
|
|
79
|
-
|
|
80
|
-
```ts
|
|
81
|
-
const state = reactive({ count: 0 })
|
|
82
|
-
|
|
83
|
-
// ❌ Loses reactivity
|
|
84
|
-
let { count } = state
|
|
85
|
-
|
|
86
|
-
// ✅ Use toRefs
|
|
87
|
-
import { toRefs } from 'vue'
|
|
88
|
-
const { count } = toRefs(state)
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
## Recommendation
|
|
92
|
-
|
|
93
|
-
Use `ref()` as the primary API for declaring reactive state - it works with any value type and has consistent behavior.
|
|
94
|
-
|
|
95
|
-
## Deep Reactivity
|
|
96
|
-
|
|
97
|
-
Both `ref()` and `reactive()` are deeply reactive by default:
|
|
98
|
-
|
|
99
|
-
```ts
|
|
100
|
-
const obj = ref({
|
|
101
|
-
nested: { count: 0 },
|
|
102
|
-
arr: ['foo', 'bar']
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
// These trigger updates
|
|
106
|
-
obj.value.nested.count++
|
|
107
|
-
obj.value.arr.push('baz')
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
Use `shallowRef()` or `shallowReactive()` to opt out of deep reactivity for performance.
|
|
111
|
-
|
|
112
|
-
## DOM Update Timing
|
|
113
|
-
|
|
114
|
-
DOM updates are batched and asynchronous. Use `nextTick()` to wait for updates:
|
|
115
|
-
|
|
116
|
-
```ts
|
|
117
|
-
import { ref, nextTick } from 'vue'
|
|
118
|
-
|
|
119
|
-
const count = ref(0)
|
|
120
|
-
|
|
121
|
-
async function increment() {
|
|
122
|
-
count.value++
|
|
123
|
-
await nextTick()
|
|
124
|
-
// DOM is now updated
|
|
125
|
-
}
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
## Ref Unwrapping Rules
|
|
129
|
-
|
|
130
|
-
- **In templates**: Top-level refs auto-unwrap
|
|
131
|
-
- **In reactive objects**: Refs auto-unwrap when accessed as properties
|
|
132
|
-
- **In arrays/collections**: Refs do NOT auto-unwrap
|
|
133
|
-
|
|
134
|
-
```ts
|
|
135
|
-
const count = ref(0)
|
|
136
|
-
const state = reactive({ count })
|
|
137
|
-
|
|
138
|
-
console.log(state.count) // 0 (unwrapped)
|
|
139
|
-
|
|
140
|
-
const books = reactive([ref('Vue Guide')])
|
|
141
|
-
console.log(books[0].value) // Need .value
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
## computed()
|
|
145
|
-
|
|
146
|
-
Derive values from reactive state with automatic caching. Only re-evaluates when dependencies change.
|
|
147
|
-
|
|
148
|
-
```ts
|
|
149
|
-
import { ref, computed } from 'vue'
|
|
150
|
-
|
|
151
|
-
const firstName = ref('John')
|
|
152
|
-
const lastName = ref('Doe')
|
|
153
|
-
|
|
154
|
-
// Readonly computed
|
|
155
|
-
const fullName = computed(() => `${firstName.value} ${lastName.value}`)
|
|
156
|
-
|
|
157
|
-
// Writable computed
|
|
158
|
-
const fullNameWritable = computed({
|
|
159
|
-
get() {
|
|
160
|
-
return `${firstName.value} ${lastName.value}`
|
|
161
|
-
},
|
|
162
|
-
set(newValue: string) {
|
|
163
|
-
[firstName.value, lastName.value] = newValue.split(' ')
|
|
164
|
-
}
|
|
165
|
-
})
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
### Computed Best Practices
|
|
169
|
-
|
|
170
|
-
- **Getters should be pure** - no side effects, no mutating other state
|
|
171
|
-
- **Don't mutate computed values** - mutate the source instead
|
|
172
|
-
- **Use computed over methods** for derived data (caching benefit)
|
|
173
|
-
|
|
174
|
-
```ts
|
|
175
|
-
// ✅ Cached - only recalculates when items changes
|
|
176
|
-
const activeItems = computed(() => items.value.filter(x => x.active))
|
|
177
|
-
|
|
178
|
-
// ❌ Not cached - runs on every render
|
|
179
|
-
function getActiveItems() {
|
|
180
|
-
return items.value.filter(x => x.active)
|
|
181
|
-
}
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
## watch()
|
|
185
|
-
|
|
186
|
-
Explicitly watch reactive sources and run side effects when they change. Lazy by default.
|
|
187
|
-
|
|
188
|
-
```ts
|
|
189
|
-
import { ref, watch } from 'vue'
|
|
190
|
-
|
|
191
|
-
const id = ref(1)
|
|
192
|
-
|
|
193
|
-
watch(id, async (newId, oldId) => {
|
|
194
|
-
const data = await fetchData(newId)
|
|
195
|
-
// handle data...
|
|
196
|
-
})
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
### Watch Source Types
|
|
200
|
-
|
|
201
|
-
```ts
|
|
202
|
-
const x = ref(0)
|
|
203
|
-
const obj = reactive({ count: 0 })
|
|
204
|
-
|
|
205
|
-
// Single ref
|
|
206
|
-
watch(x, (newX) => console.log(newX))
|
|
207
|
-
|
|
208
|
-
// Getter function
|
|
209
|
-
watch(() => obj.count, (count) => console.log(count))
|
|
210
|
-
|
|
211
|
-
// Multiple sources
|
|
212
|
-
watch([x, () => obj.count], ([newX, newCount]) => {
|
|
213
|
-
console.log(newX, newCount)
|
|
214
|
-
})
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
### Watch Options
|
|
218
|
-
|
|
219
|
-
```ts
|
|
220
|
-
watch(source, callback, {
|
|
221
|
-
immediate: true, // Run immediately on creation
|
|
222
|
-
deep: true, // Watch nested properties
|
|
223
|
-
once: true, // Trigger only once (3.4+)
|
|
224
|
-
flush: 'post' // Run after DOM update
|
|
225
|
-
})
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
## watchEffect()
|
|
229
|
-
|
|
230
|
-
Automatically tracks dependencies and runs immediately. Re-runs when any tracked dependency changes.
|
|
231
|
-
|
|
232
|
-
```ts
|
|
233
|
-
import { ref, watchEffect } from 'vue'
|
|
234
|
-
|
|
235
|
-
const todoId = ref(1)
|
|
236
|
-
const data = ref(null)
|
|
237
|
-
|
|
238
|
-
watchEffect(async () => {
|
|
239
|
-
const response = await fetch(`/api/todos/${todoId.value}`)
|
|
240
|
-
data.value = await response.json()
|
|
241
|
-
})
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
### watch vs watchEffect
|
|
245
|
-
|
|
246
|
-
| Feature | watch | watchEffect |
|
|
247
|
-
| ------------------- | ---------------- | --------------------- |
|
|
248
|
-
| Dependency tracking | Explicit | Automatic |
|
|
249
|
-
| Lazy | Yes | No (immediate) |
|
|
250
|
-
| Access old value | Yes | No |
|
|
251
|
-
| Best for | Specific sources | Multiple dependencies |
|
|
252
|
-
|
|
253
|
-
## Watcher Cleanup (3.5+)
|
|
254
|
-
|
|
255
|
-
Cancel stale async operations:
|
|
256
|
-
|
|
257
|
-
```ts
|
|
258
|
-
import { watch, onWatcherCleanup } from 'vue'
|
|
259
|
-
|
|
260
|
-
watch(id, async (newId) => {
|
|
261
|
-
const controller = new AbortController()
|
|
262
|
-
|
|
263
|
-
fetch(`/api/${newId}`, { signal: controller.signal })
|
|
264
|
-
|
|
265
|
-
onWatcherCleanup(() => controller.abort())
|
|
266
|
-
})
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
## Stopping Watchers
|
|
270
|
-
|
|
271
|
-
```ts
|
|
272
|
-
const stop = watch(source, callback)
|
|
273
|
-
const stop2 = watchEffect(() => { /* ... */ })
|
|
274
|
-
|
|
275
|
-
// Stop manually
|
|
276
|
-
stop()
|
|
277
|
-
stop2()
|
|
278
|
-
|
|
279
|
-
// Pause/Resume (3.5+)
|
|
280
|
-
const { stop, pause, resume } = watchEffect(() => { /* ... */ })
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
<!--
|
|
284
|
-
Source references:
|
|
285
|
-
- https://vuejs.org/guide/essentials/reactivity-fundamentals.html
|
|
286
|
-
- https://vuejs.org/guide/essentials/computed.html
|
|
287
|
-
- https://vuejs.org/guide/essentials/watchers.html
|
|
288
|
-
- https://vuejs.org/api/reactivity-core.html
|
|
289
|
-
-->
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
# Vue Router Typing
|
|
2
|
-
|
|
3
|
-
Type-safe routing patterns for Vue Router.
|
|
4
|
-
|
|
5
|
-
> **For Nuxt:** Use file-based routing instead. See `nuxt` skill for Nuxt routing patterns.
|
|
6
|
-
|
|
7
|
-
## Route Meta Types
|
|
8
|
-
|
|
9
|
-
Extend `RouteMeta` for typed route.meta:
|
|
10
|
-
|
|
11
|
-
```ts
|
|
12
|
-
// router/types.ts
|
|
13
|
-
import 'vue-router'
|
|
14
|
-
|
|
15
|
-
declare module 'vue-router' {
|
|
16
|
-
interface RouteMeta {
|
|
17
|
-
requiresAuth?: boolean
|
|
18
|
-
title?: string
|
|
19
|
-
roles?: ('admin' | 'user')[]
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
**Usage:**
|
|
25
|
-
|
|
26
|
-
```ts
|
|
27
|
-
const route = useRoute()
|
|
28
|
-
route.meta.requiresAuth // boolean | undefined (typed!)
|
|
29
|
-
route.meta.title // string | undefined
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
## Typed Route Params with unplugin-vue-router
|
|
33
|
-
|
|
34
|
-
Use `unplugin-vue-router` for fully typed routes:
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
pnpm add -D unplugin-vue-router
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
```ts
|
|
41
|
-
// vite.config.ts
|
|
42
|
-
import VueRouter from 'unplugin-vue-router/vite'
|
|
43
|
-
|
|
44
|
-
export default defineConfig({
|
|
45
|
-
plugins: [VueRouter(), Vue()], // VueRouter BEFORE Vue
|
|
46
|
-
})
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
**Typed useRoute:**
|
|
50
|
-
|
|
51
|
-
```ts
|
|
52
|
-
// Auto-generated route types from file structure
|
|
53
|
-
const route = useRoute('/users/[id]')
|
|
54
|
-
route.params.id // string (typed!)
|
|
55
|
-
|
|
56
|
-
const route = useRoute('/posts/[...slug]')
|
|
57
|
-
route.params.slug // string[] (typed!)
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
**Typed router.push:**
|
|
61
|
-
|
|
62
|
-
```ts
|
|
63
|
-
const router = useRouter()
|
|
64
|
-
|
|
65
|
-
// ✅ Type-checked
|
|
66
|
-
router.push({ name: '/users/[id]', params: { id: '123' } })
|
|
67
|
-
|
|
68
|
-
// ❌ TypeScript error - wrong param
|
|
69
|
-
router.push({ name: '/users/[id]', params: { userId: '123' } })
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
## Scroll Behavior Types
|
|
73
|
-
|
|
74
|
-
Type scroll behavior function:
|
|
75
|
-
|
|
76
|
-
```ts
|
|
77
|
-
import type { RouterScrollBehavior } from 'vue-router'
|
|
78
|
-
|
|
79
|
-
const scrollBehavior: RouterScrollBehavior = (to, from, savedPosition) => {
|
|
80
|
-
if (savedPosition) return savedPosition
|
|
81
|
-
if (to.hash) return { el: to.hash, behavior: 'smooth' }
|
|
82
|
-
return { top: 0 }
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const router = createRouter({
|
|
86
|
-
history: createWebHistory(),
|
|
87
|
-
routes,
|
|
88
|
-
scrollBehavior,
|
|
89
|
-
})
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
## Dynamic Route Params
|
|
93
|
-
|
|
94
|
-
Handle union types for dynamic segments:
|
|
95
|
-
|
|
96
|
-
```ts
|
|
97
|
-
// routes/[type].vue where type can be 'posts' | 'users' | 'comments'
|
|
98
|
-
const route = useRoute()
|
|
99
|
-
|
|
100
|
-
// Narrow params type
|
|
101
|
-
type ContentType = 'posts' | 'users' | 'comments'
|
|
102
|
-
|
|
103
|
-
const type = route.params.type as ContentType
|
|
104
|
-
|
|
105
|
-
// Or use route guards
|
|
106
|
-
if (route.params.type === 'posts') {
|
|
107
|
-
// TypeScript knows type is 'posts'
|
|
108
|
-
}
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
## Navigation Guards Types
|
|
112
|
-
|
|
113
|
-
Type navigation guards:
|
|
114
|
-
|
|
115
|
-
```ts
|
|
116
|
-
import type { NavigationGuardWithThis, RouteLocationNormalized } from 'vue-router'
|
|
117
|
-
|
|
118
|
-
const authGuard: NavigationGuardWithThis<undefined> = (to, from) => {
|
|
119
|
-
if (to.meta.requiresAuth && !isAuthenticated()) {
|
|
120
|
-
return { name: 'login', query: { redirect: to.fullPath } }
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
router.beforeEach(authGuard)
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
**Per-route guards:**
|
|
128
|
-
|
|
129
|
-
```ts
|
|
130
|
-
const routes = [
|
|
131
|
-
{
|
|
132
|
-
path: '/admin',
|
|
133
|
-
component: AdminPage,
|
|
134
|
-
beforeEnter: (to: RouteLocationNormalized) => {
|
|
135
|
-
if (!hasAdminRole()) return { name: 'forbidden' }
|
|
136
|
-
},
|
|
137
|
-
},
|
|
138
|
-
]
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
## RouteLocation Types
|
|
142
|
-
|
|
143
|
-
Common route types:
|
|
144
|
-
|
|
145
|
-
```ts
|
|
146
|
-
import type {
|
|
147
|
-
RouteLocationNormalized, // Resolved route (after navigation)
|
|
148
|
-
RouteLocationNormalizedLoaded, // Current route (from useRoute)
|
|
149
|
-
RouteLocationRaw, // Input to router.push()
|
|
150
|
-
RouteRecordRaw, // Route config definition
|
|
151
|
-
} from 'vue-router'
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
## Common Mistakes
|
|
155
|
-
|
|
156
|
-
**Not extending RouteMeta module:**
|
|
157
|
-
|
|
158
|
-
```ts
|
|
159
|
-
// ❌ Loses type info
|
|
160
|
-
route.meta.customField // any
|
|
161
|
-
|
|
162
|
-
// ✅ Extend the interface
|
|
163
|
-
declare module 'vue-router' {
|
|
164
|
-
interface RouteMeta { customField: string }
|
|
165
|
-
}
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
**Assuming params are always strings:**
|
|
169
|
-
|
|
170
|
-
```ts
|
|
171
|
-
// Catch-all routes have string[] params
|
|
172
|
-
const route = useRoute()
|
|
173
|
-
|
|
174
|
-
// ❌ May be string[]
|
|
175
|
-
const id = route.params.id
|
|
176
|
-
|
|
177
|
-
// ✅ Handle both cases
|
|
178
|
-
const id = Array.isArray(route.params.id)
|
|
179
|
-
? route.params.id[0]
|
|
180
|
-
: route.params.id
|
|
181
|
-
```
|