Skip to content

Commit 42c027a

Browse files
authored
feat: add useRefDebounced (#579)
* feat: add `useRefDebounced` * chore: export file * chore: add tests and docs * chore: rename to refDebounced
1 parent 866928c commit 42c027a

File tree

11 files changed

+97
-0
lines changed

11 files changed

+97
-0
lines changed

docs/.vuepress/config.js

+1
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ module.exports = {
147147
["composable/misc/vmodel", "vModel"],
148148
["composable/misc/injectFactory", "injectFactory"],
149149
["composable/misc/lockScroll", "lockScroll"],
150+
["composable/misc/refDebounced", "refDebounced"],
150151
],
151152
},
152153
{

docs/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ Check out the [examples folder](examples) or start hacking on [codesandbox](http
8282
- [injectFactory](composable/misc/injectFactory) - same as [inject](https://vue-composition-api-rfc.netlify.app/api.html#dependency-injection) but allows you to have a factory as default value
8383
- [interval](composable/misc/interval) - self-remove `setInterval` on unmount
8484
- [lockScroll](composable/misc/lockScroll) - `lock-scroll` component
85+
- [refDebounced](composable/misc/refDebounced) - debounces the update value of a `ref`
8586

8687
### Storage
8788

docs/composable/misc/refDebounced.md

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# refDebounced
2+
3+
> debounces the update value of a `ref`
4+
5+
## Parameters
6+
7+
```js
8+
import { refDebounced } from "vue-composable";
9+
10+
refDebounced(delay);
11+
refDebounced(value, delay);
12+
```
13+
14+
| Parameters | Type | Required | Default | Description |
15+
| ---------- | -------- | -------- | ----------- | -------------- |
16+
| `delay` | `number` | `true` | | debounce delay |
17+
| `value` | `T` | `false` | `undefined` | initial value |
18+
19+
## State
20+
21+
The `refDebounced` function retuns a `ref`:
22+
23+
```js
24+
import { refDebounced } from "vue-composable";
25+
26+
const debouncedValue = refDebounced();
27+
```
28+
29+
| State | Type | Description |
30+
| -------------- | -------- | --------------- |
31+
| debouncedValue | `Ref<T>` | debounced `ref` |

packages/vue-composable/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ Check our [documentation](https://pikax.me/vue-composable/)
8181
- [injectFactory](https://pikax.me/vue-composable/composable/misc/injectFactory) - same as [inject](https://vue-composition-api-rfc.netlify.app/api.html#dependency-injection) but allows you to have a factory as default value
8282
- [interval](https://pikax.me/vue-composable/composable/misc/interval) - self-remove `setInterval` on unmount
8383
- [lockScroll](https://pikax.me/vue-composable/composable/misc/lockScroll) - `lock-scroll` component
84+
- [refDebounced](https://pikax.me/vue-composable/composable/misc/refDebounced) - debounces the update value of a `ref`
8485

8586
### Storage
8687

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { refDebounced } from "../../src";
2+
3+
describe("refDebounced", () => {
4+
beforeAll(() => {
5+
jest.useFakeTimers();
6+
});
7+
afterAll(() => {
8+
jest.useRealTimers();
9+
});
10+
it("should work", () => {
11+
const r = refDebounced("a", 1);
12+
13+
expect(r.value).toBe("a");
14+
15+
r.value = "b";
16+
17+
// should not been updated yet
18+
expect(r.value).toBe("a");
19+
20+
jest.runTimersToTime(2);
21+
expect(r.value).toBe("b");
22+
});
23+
24+
it("should allow use only a delay", () => {
25+
const r = refDebounced(1);
26+
expect(r.value).toBe(undefined);
27+
28+
r.value = 1;
29+
30+
// should not been updated yet
31+
expect(r.value).toBe(undefined);
32+
33+
jest.runTimersToTime(2);
34+
expect(r.value).toBe(1);
35+
});
36+
});

packages/vue-composable/src/api.2.ts

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export {
2121
ComputedRef,
2222
toRaw,
2323
UnwrapRef, // Plugin,
24+
customRef,
2425
} from "@vue/composition-api";
2526
export { VueConstructor as App } from "vue";
2627

packages/vue-composable/src/api.3.ts

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export {
2525
readonly,
2626
toRaw,
2727
DeepReadonly,
28+
customRef,
2829
} from "@vue/runtime-core";
2930

3031
// istanbul ignore next

packages/vue-composable/src/api.ts

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export {
2525
readonly,
2626
toRaw,
2727
DeepReadonly,
28+
customRef,
2829
} from "@vue/runtime-core";
2930

3031
// istanbul ignore next

packages/vue-composable/src/misc/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ export * from "./lockScroll";
44
export * from "./vmodel";
55
export * from "./injectFactory";
66
export * from "./interval";
7+
export * from "./refDebounced";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Ref, customRef } from "../api";
2+
import { debounce } from "../debounce";
3+
import { isNumber } from "../utils";
4+
5+
export function refDebounced<T>(delay: number): Ref<T | undefined>;
6+
export function refDebounced<T>(value: T, delay: number): Ref<T | undefined>;
7+
export function refDebounced<T>(value: T | number, delay?: number): Ref<T> {
8+
let [v, d] =
9+
arguments.length === 1 && isNumber(value)
10+
? [undefined, value]
11+
: [value, delay];
12+
return customRef<T>((track, trigger) => ({
13+
get() {
14+
track();
15+
return v as any;
16+
},
17+
set: debounce((val) => {
18+
v = val;
19+
trigger();
20+
}, d),
21+
}));
22+
}

readme.md

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ Check our [documentation](https://pikax.me/vue-composable/)
8181
- [injectFactory](https://pikax.me/vue-composable/composable/misc/injectFactory) - same as [inject](https://vue-composition-api-rfc.netlify.app/api.html#dependency-injection) but allows you to have a factory as default value
8282
- [interval](https://pikax.me/vue-composable/composable/misc/interval) - self-remove `setInterval` on unmount
8383
- [lockScroll](https://pikax.me/vue-composable/composable/misc/lockScroll) - `lock-scroll` component
84+
- [refDebounced](https://pikax.me/vue-composable/composable/misc/refDebounced) - debounces the update value of a `ref`
8485

8586
### Storage
8687

0 commit comments

Comments
 (0)