Skip to content

Commit 0af66f6

Browse files
committed
chore: add VueUse functions skill and wayfinder cache
1 parent f7addb1 commit 0af66f6

File tree

268 files changed

+24581
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

268 files changed

+24581
-0
lines changed

.agents/skills/vueuse-functions/SKILL.md

Lines changed: 417 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
---
2+
category: Reactivity
3+
alias: asyncComputed
4+
---
5+
6+
# computedAsync
7+
8+
Computed for async functions.
9+
10+
## Usage
11+
12+
```ts
13+
import { computedAsync } from "@vueuse/core";
14+
import { shallowRef } from "vue";
15+
16+
const name = shallowRef("jack");
17+
18+
const userInfo = computedAsync(
19+
async () => {
20+
return await mockLookUp(name.value);
21+
},
22+
null, // initial state
23+
);
24+
```
25+
26+
### Evaluation State
27+
28+
Pass a ref to track if the async function is currently evaluating.
29+
30+
```ts
31+
import { computedAsync } from "@vueuse/core";
32+
import { shallowRef } from "vue";
33+
34+
const evaluating = shallowRef(false);
35+
36+
const userInfo = computedAsync(
37+
async () => {
38+
/* your logic */
39+
},
40+
null,
41+
evaluating, // can also be passed via options: { evaluating }
42+
);
43+
```
44+
45+
### onCancel
46+
47+
When the computed source changes before the previous async function resolves, you may want to cancel the previous one. Here is an example showing how to incorporate with the fetch API.
48+
49+
```ts
50+
import { computedAsync } from "@vueuse/core";
51+
import { shallowRef } from "vue";
52+
53+
const packageName = shallowRef("@vueuse/core");
54+
55+
const downloads = computedAsync(async (onCancel) => {
56+
const abortController = new AbortController();
57+
58+
onCancel(() => abortController.abort());
59+
60+
return await fetch(`https://api.npmjs.org/downloads/point/last-week/${packageName.value}`, {
61+
signal: abortController.signal,
62+
})
63+
.then((response) => (response.ok ? response.json() : { downloads: "" }))
64+
.then((result) => result.downloads);
65+
}, 0);
66+
```
67+
68+
### Lazy
69+
70+
By default, `computedAsync` will start resolving immediately on creation. Specify `lazy: true` to make it start resolving on the first access.
71+
72+
```ts
73+
import { computedAsync } from "@vueuse/core";
74+
import { shallowRef } from "vue";
75+
76+
const evaluating = shallowRef(false);
77+
78+
const userInfo = computedAsync(
79+
async () => {
80+
/* your logic */
81+
},
82+
null,
83+
{ lazy: true, evaluating },
84+
);
85+
```
86+
87+
### Error Handling
88+
89+
Use the `onError` callback to handle errors from the async function.
90+
91+
```ts
92+
import { computedAsync } from "@vueuse/core";
93+
import { shallowRef } from "vue";
94+
95+
const name = shallowRef("jack");
96+
97+
const userInfo = computedAsync(
98+
async () => {
99+
return await mockLookUp(name.value);
100+
},
101+
null,
102+
{
103+
onError(e) {
104+
console.error("Failed to fetch user info", e);
105+
},
106+
},
107+
);
108+
```
109+
110+
### Shallow Ref
111+
112+
By default, `computedAsync` uses `shallowRef` internally. Set `shallow: false` to use a deep ref instead.
113+
114+
```ts
115+
import { computedAsync } from "@vueuse/core";
116+
import { shallowRef } from "vue";
117+
118+
const name = shallowRef("jack");
119+
120+
const userInfo = computedAsync(
121+
async () => {
122+
return await fetchNestedData(name.value);
123+
},
124+
null,
125+
{ shallow: false }, // enables deep reactivity
126+
);
127+
```
128+
129+
## Caveats
130+
131+
- Just like Vue's built-in `computed` function, `computedAsync` does dependency tracking and is automatically re-evaluated when dependencies change. Note however that only dependencies referenced in the first call stack are considered for this. In other words: **Dependencies that are accessed asynchronously will not trigger re-evaluation of the async computed value.**
132+
133+
- As opposed to Vue's built-in `computed` function, re-evaluation of the async computed value is triggered whenever dependencies are changing, regardless of whether its result is currently being tracked or not.
134+
135+
## Type Declarations
136+
137+
```ts
138+
/**
139+
* Handle overlapping async evaluations.
140+
*
141+
* @param cancelCallback The provided callback is invoked when a re-evaluation of the computed value is triggered before the previous one finished
142+
*/
143+
export type AsyncComputedOnCancel = (cancelCallback: Fn) => void;
144+
export interface AsyncComputedOptions<Lazy = boolean> extends ConfigurableFlushSync {
145+
/**
146+
* Should value be evaluated lazily
147+
*
148+
* @default false
149+
*/
150+
lazy?: Lazy;
151+
/**
152+
* Ref passed to receive the updated of async evaluation
153+
*/
154+
evaluating?: Ref<boolean>;
155+
/**
156+
* Use shallowRef
157+
*
158+
* @default true
159+
*/
160+
shallow?: boolean;
161+
/**
162+
* Callback when error is caught.
163+
*/
164+
onError?: (e: unknown) => void;
165+
}
166+
/**
167+
* Create an asynchronous computed dependency.
168+
*
169+
* @see https://vueuse.org/computedAsync
170+
* @param evaluationCallback The promise-returning callback which generates the computed value
171+
* @param initialState The initial state, used until the first evaluation finishes
172+
* @param optionsOrRef Additional options or a ref passed to receive the updates of the async evaluation
173+
*/
174+
export declare function computedAsync<T>(
175+
evaluationCallback: (onCancel: AsyncComputedOnCancel) => T | Promise<T>,
176+
initialState: T,
177+
optionsOrRef: AsyncComputedOptions<true>,
178+
): ComputedRef<T>;
179+
export declare function computedAsync<T>(
180+
evaluationCallback: (onCancel: AsyncComputedOnCancel) => T | Promise<T>,
181+
initialState: undefined,
182+
optionsOrRef: AsyncComputedOptions<true>,
183+
): ComputedRef<T | undefined>;
184+
export declare function computedAsync<T>(
185+
evaluationCallback: (onCancel: AsyncComputedOnCancel) => T | Promise<T>,
186+
initialState: T,
187+
optionsOrRef?: Ref<boolean> | AsyncComputedOptions,
188+
): Ref<T>;
189+
export declare function computedAsync<T>(
190+
evaluationCallback: (onCancel: AsyncComputedOnCancel) => T | Promise<T>,
191+
initialState?: undefined,
192+
optionsOrRef?: Ref<boolean> | AsyncComputedOptions,
193+
): Ref<T | undefined>;
194+
/** @deprecated use `computedAsync` instead */
195+
export declare const asyncComputed: typeof computedAsync;
196+
```
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
category: Reactivity
3+
alias: eagerComputed
4+
---
5+
6+
# computedEager
7+
8+
Eager computed without lazy evaluation.
9+
10+
::: info
11+
This function will be removed in future version.
12+
:::
13+
14+
::: tip
15+
Note💡: If you are using Vue 3.4+, you can use `computed` right away, you no longer need this function.
16+
In Vue 3.4+, if the computed new value does not change, `computed`, `effect`, `watch`, `watchEffect`, `render` dependencies will not be triggered.
17+
See: https://github.com/vuejs/core/pull/5912
18+
:::
19+
20+
Learn more at [Vue: When a computed property can be the wrong tool](https://dev.to/linusborg/vue-when-a-computed-property-can-be-the-wrong-tool-195j).
21+
22+
- Use `computed()` when you have a complex calculation going on, which can actually profit from caching and lazy evaluation and should only be (re-)calculated if really necessary.
23+
- Use `computedEager()` when you have a simple operation, with a rarely changing return value – often a boolean.
24+
25+
## Usage
26+
27+
```ts
28+
import { computedEager } from "@vueuse/core";
29+
30+
const todos = ref([]);
31+
const hasOpenTodos = computedEager(() => !!todos.length);
32+
33+
console.log(hasOpenTodos.value); // false
34+
toTodos.value.push({ title: "Learn Vue" });
35+
console.log(hasOpenTodos.value); // true
36+
```
37+
38+
## Type Declarations
39+
40+
```ts
41+
export type ComputedEagerOptions = WatchOptionsBase;
42+
export type ComputedEagerReturn<T = any> = Readonly<ShallowRef<T>>;
43+
/**
44+
*
45+
* @deprecated This function will be removed in future version.
46+
*
47+
* Note: If you are using Vue 3.4+, you can straight use computed instead.
48+
* Because in Vue 3.4+, if computed new value does not change,
49+
* computed, effect, watch, watchEffect, render dependencies will not be triggered.
50+
* refer: https://github.com/vuejs/core/pull/5912
51+
*
52+
* @param fn effect function
53+
* @param options WatchOptionsBase
54+
* @returns readonly shallowRef
55+
*/
56+
export declare function computedEager<T>(
57+
fn: () => T,
58+
options?: ComputedEagerOptions,
59+
): ComputedEagerReturn<T>;
60+
/** @deprecated use `computedEager` instead */
61+
export declare const eagerComputed: typeof computedEager;
62+
```
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
---
2+
category: Component
3+
---
4+
5+
# computedInject
6+
7+
Combine `computed` and `inject`. Useful for creating a computed property based on an injected value.
8+
9+
## Usage
10+
11+
In Provider Component
12+
13+
```ts twoslash include main
14+
import type { InjectionKey, Ref } from "vue";
15+
import { provide, ref } from "vue";
16+
17+
interface Item {
18+
key: number;
19+
value: string;
20+
}
21+
22+
export const ArrayKey: InjectionKey<Ref<Item[]>> = Symbol("symbol-key");
23+
24+
const array = ref([
25+
{ key: 1, value: "1" },
26+
{ key: 2, value: "2" },
27+
{ key: 3, value: "3" },
28+
]);
29+
30+
provide(ArrayKey, array);
31+
```
32+
33+
In Receiver Component
34+
35+
```ts
36+
// @filename: provider.ts
37+
// @include: main
38+
// ---cut---
39+
import { computedInject } from "@vueuse/core";
40+
41+
import { ArrayKey } from "./provider";
42+
43+
const computedArray = computedInject(ArrayKey, (source) => {
44+
const arr = [...source.value];
45+
arr.unshift({ key: 0, value: "all" });
46+
return arr;
47+
});
48+
```
49+
50+
### Default Value
51+
52+
You can provide a default value that will be used if the injection key is not provided by a parent component.
53+
54+
```ts
55+
import { computedInject } from "@vueuse/core";
56+
57+
const computedArray = computedInject(
58+
ArrayKey,
59+
(source) => {
60+
return source.value.map((item) => item.value);
61+
},
62+
ref([]), // default source value
63+
);
64+
```
65+
66+
### Factory Default
67+
68+
Pass `true` as the fourth argument to treat the default value as a factory function.
69+
70+
```ts
71+
import { computedInject } from "@vueuse/core";
72+
73+
const computedArray = computedInject(
74+
ArrayKey,
75+
(source) => {
76+
return source.value.map((item) => item.value);
77+
},
78+
() => ref([]), // factory function for default
79+
true, // treat default as factory
80+
);
81+
```
82+
83+
### Writable Computed
84+
85+
You can also create a writable computed property by passing an object with `get` and `set` functions.
86+
87+
```ts
88+
import { computedInject } from "@vueuse/core";
89+
90+
const computedArray = computedInject(ArrayKey, {
91+
get(source) {
92+
return source.value.map((item) => item.value);
93+
},
94+
set(value) {
95+
// handle setting the value
96+
console.log("Setting value:", value);
97+
},
98+
});
99+
```
100+
101+
## Type Declarations
102+
103+
```ts
104+
export type ComputedInjectGetter<T, K> = (source: T | undefined, oldValue?: K) => K;
105+
export type ComputedInjectGetterWithDefault<T, K> = (source: T, oldValue?: K) => K;
106+
export type ComputedInjectSetter<T> = (v: T) => void;
107+
export interface WritableComputedInjectOptions<T, K> {
108+
get: ComputedInjectGetter<T, K>;
109+
set: ComputedInjectSetter<K>;
110+
}
111+
export interface WritableComputedInjectOptionsWithDefault<T, K> {
112+
get: ComputedInjectGetterWithDefault<T, K>;
113+
set: ComputedInjectSetter<K>;
114+
}
115+
export declare function computedInject<T, K = any>(
116+
key: InjectionKey<T> | string,
117+
getter: ComputedInjectGetter<T, K>,
118+
): ComputedRef<K | undefined>;
119+
export declare function computedInject<T, K = any>(
120+
key: InjectionKey<T> | string,
121+
options: WritableComputedInjectOptions<T, K>,
122+
): ComputedRef<K | undefined>;
123+
export declare function computedInject<T, K = any>(
124+
key: InjectionKey<T> | string,
125+
getter: ComputedInjectGetterWithDefault<T, K>,
126+
defaultSource: T,
127+
treatDefaultAsFactory?: false,
128+
): ComputedRef<K>;
129+
export declare function computedInject<T, K = any>(
130+
key: InjectionKey<T> | string,
131+
options: WritableComputedInjectOptionsWithDefault<T, K>,
132+
defaultSource: T | (() => T),
133+
treatDefaultAsFactory: true,
134+
): ComputedRef<K>;
135+
```

0 commit comments

Comments
 (0)