0
# Reactivity Utilities
1
2
Core utilities for working with Vue's reactivity system, including conversion between refs and reactive objects, and reactive function transformation.
3
4
## Capabilities
5
6
### reactify
7
8
Converts a plain function into a reactive version that automatically unwraps reactive arguments.
9
10
```typescript { .api }
11
/**
12
* Converts a plain function into reactive version
13
* @param fn - Function to make reactive
14
* @param options - Reactify options
15
* @returns Reactive version of the function
16
*/
17
function reactify<T extends Function>(
18
fn: T,
19
options?: ReactifyOptions<boolean>
20
): ReactifyReturn<T>;
21
22
interface ReactifyOptions<T extends boolean> {
23
computedGetter?: T;
24
}
25
26
type ReactifyReturn<T> = T extends (...args: any[]) => any
27
? (...args: Parameters<T>) => ComputedRef<ReturnType<T>>
28
: T;
29
```
30
31
**Usage Example:**
32
33
```typescript
34
import { reactify, ref } from "@vueuse/shared";
35
36
// Original function
37
const add = (a: number, b: number) => a + b;
38
39
// Reactive version
40
const reactiveAdd = reactify(add);
41
42
const a = ref(1);
43
const b = ref(2);
44
45
// Result is a computed ref that updates when a or b change
46
const sum = reactiveAdd(a, b); // ComputedRef<number>
47
console.log(sum.value); // 3
48
49
a.value = 5;
50
console.log(sum.value); // 7
51
```
52
53
### reactifyObject
54
55
Applies reactify to every property of an object.
56
57
```typescript { .api }
58
/**
59
* Applies reactify to every property of an object
60
* @param obj - Object with functions to reactify
61
* @param optionsMap - Map of options for each property
62
* @returns Object with reactive versions of functions
63
*/
64
function reactifyObject<T extends Record<string, Function>>(
65
obj: T,
66
optionsMap?: ReactifyObjectOptions<T>
67
): ReactifyObjectReturn<T>;
68
69
type ReactifyObjectOptions<T> = {
70
[K in keyof T]?: ReactifyOptions<boolean>;
71
};
72
73
type ReactifyObjectReturn<T> = {
74
[K in keyof T]: ReactifyReturn<T[K]>;
75
};
76
```
77
78
**Usage Example:**
79
80
```typescript
81
import { reactifyObject, ref } from "@vueuse/shared";
82
83
const math = reactifyObject({
84
add: (a: number, b: number) => a + b,
85
multiply: (a: number, b: number) => a * b,
86
});
87
88
const x = ref(3);
89
const y = ref(4);
90
91
const sum = math.add(x, y); // ComputedRef<number>
92
const product = math.multiply(x, y); // ComputedRef<number>
93
94
console.log(sum.value); // 7
95
console.log(product.value); // 12
96
```
97
98
### toReactive
99
100
Converts a ref to a reactive object.
101
102
```typescript { .api }
103
/**
104
* Converts ref to reactive object
105
* @param objectRef - Ref containing an object
106
* @returns Reactive version of the object
107
*/
108
function toReactive<T extends Record<string, any>>(
109
objectRef: MaybeRef<T>
110
): T;
111
```
112
113
**Usage Example:**
114
115
```typescript
116
import { toReactive, ref } from "@vueuse/shared";
117
118
const objectRef = ref({ name: 'John', age: 30 });
119
const reactiveObj = toReactive(objectRef);
120
121
// Access properties directly without .value
122
console.log(reactiveObj.name); // 'John'
123
reactiveObj.age = 31; // Updates the original ref
124
```
125
126
### syncRef
127
128
Two-way synchronization between refs.
129
130
```typescript { .api }
131
/**
132
* Two-way refs synchronization
133
* @param left - Left ref to sync
134
* @param right - Right ref to sync
135
* @param options - Sync options
136
* @returns Stop function
137
*/
138
function syncRef<L, R>(
139
left: Ref<L>,
140
right: Ref<R>,
141
options?: SyncRefOptions
142
): () => void;
143
144
interface SyncRefOptions {
145
direction?: 'ltr' | 'rtl' | 'both';
146
flush?: 'pre' | 'post' | 'sync';
147
deep?: boolean;
148
immediate?: boolean;
149
transform?: {
150
ltr?: (left: L) => R;
151
rtl?: (right: R) => L;
152
};
153
}
154
```
155
156
**Usage Example:**
157
158
```typescript
159
import { syncRef, ref } from "@vueuse/shared";
160
161
const left = ref('left');
162
const right = ref('right');
163
164
// Bi-directional sync
165
const stop = syncRef(left, right);
166
167
left.value = 'updated'; // right.value becomes 'updated'
168
right.value = 'changed'; // left.value becomes 'changed'
169
170
// With transformation
171
const num = ref(0);
172
const str = ref('0');
173
174
syncRef(num, str, {
175
transform: {
176
ltr: (num) => num.toString(),
177
rtl: (str) => parseInt(str, 10)
178
}
179
});
180
```
181
182
### syncRefs
183
184
Keep target ref(s) in sync with a source ref.
185
186
```typescript { .api }
187
/**
188
* Keep target ref(s) in sync with the source ref
189
* @param source - Source watch source
190
* @param targets - Target ref or array of target refs
191
* @param options - Sync options
192
* @returns Stop function
193
*/
194
function syncRefs<T>(
195
source: WatchSource<T>,
196
targets: Ref<T> | Ref<T>[],
197
options?: SyncRefsOptions
198
): WatchStopHandle;
199
200
interface SyncRefsOptions extends ConfigurableFlushSync {
201
deep?: boolean;
202
immediate?: boolean;
203
}
204
```
205
206
**Usage Example:**
207
208
```typescript
209
import { syncRefs, ref } from "@vueuse/shared";
210
211
const source = ref('source');
212
const target1 = ref('');
213
const target2 = ref('');
214
const target3 = ref('');
215
216
const stop = syncRefs(source, [target1, target2, target3]);
217
218
source.value = 'updated'; // All targets become 'updated'
219
220
// Single target
221
const singleTarget = ref('');
222
syncRefs(source, singleTarget);
223
```
224
225
### reactiveComputed
226
227
Computed that returns a reactive object instead of a ref.
228
229
```typescript { .api }
230
/**
231
* Computed that returns reactive object instead of ref
232
* @param fn - Computation function
233
* @returns Reactive object with computed value
234
*/
235
function reactiveComputed<T extends Record<string, any>>(fn: () => T): T;
236
```
237
238
**Usage Example:**
239
240
```typescript
241
import { reactiveComputed, ref } from "@vueuse/shared";
242
243
const name = ref('John');
244
const age = ref(30);
245
246
const user = reactiveComputed(() => ({
247
fullName: `${name.value} Doe`,
248
isAdult: age.value >= 18,
249
info: `${name.value} is ${age.value} years old`
250
}));
251
252
// Access properties directly (no .value needed)
253
console.log(user.fullName); // 'John Doe'
254
console.log(user.isAdult); // true
255
256
name.value = 'Jane';
257
console.log(user.fullName); // 'Jane Doe'
258
```
259
260
### reactiveOmit
261
262
Reactively omit fields from a reactive object.
263
264
```typescript { .api }
265
/**
266
* Reactively omit fields from a reactive object
267
* @param obj - Source object
268
* @param keys - Keys to omit or predicate function
269
* @returns Reactive object with omitted fields
270
*/
271
function reactiveOmit<T extends object, K extends keyof T>(
272
obj: T,
273
...keys: (K | K[])[]
274
): ReactiveOmitReturn<T, K>;
275
276
function reactiveOmit<T extends object>(
277
obj: T,
278
predicate: ReactiveOmitPredicate<T>
279
): ReactiveOmitReturn<T>;
280
281
type ReactiveOmitReturn<T extends object, K extends keyof T | undefined = undefined> =
282
[K] extends [undefined] ? Partial<T> : Omit<T, Extract<K, keyof T>>;
283
284
type ReactiveOmitPredicate<T> = (value: T[keyof T], key: keyof T) => boolean;
285
```
286
287
**Usage Example:**
288
289
```typescript
290
import { reactiveOmit, reactive } from "@vueuse/shared";
291
292
const obj = reactive({
293
name: 'John',
294
age: 30,
295
email: 'john@example.com',
296
password: 'secret'
297
});
298
299
// Omit specific keys
300
const publicInfo = reactiveOmit(obj, 'password');
301
console.log(publicInfo); // { name: 'John', age: 30, email: 'john@example.com' }
302
303
// Omit using predicate
304
const filtered = reactiveOmit(obj, (value, key) => key.includes('pass'));
305
```
306
307
### reactivePick
308
309
Reactively pick fields from a reactive object.
310
311
```typescript { .api }
312
/**
313
* Reactively pick fields from a reactive object
314
* @param obj - Source object
315
* @param keys - Keys to pick or predicate function
316
* @returns Reactive object with picked fields
317
*/
318
function reactivePick<T extends object, K extends keyof T>(
319
obj: T,
320
...keys: (K | K[])[]
321
): ReactivePickReturn<T, K>;
322
323
function reactivePick<T extends object>(
324
obj: T,
325
predicate: ReactivePickPredicate<T>
326
): ReactivePickReturn<T, keyof T>;
327
328
type ReactivePickReturn<T extends object, K extends keyof T> = {
329
[S in K]: UnwrapRef<T[S]>;
330
};
331
332
type ReactivePickPredicate<T> = (value: T[keyof T], key: keyof T) => boolean;
333
```
334
335
**Usage Example:**
336
337
```typescript
338
import { reactivePick, reactive } from "@vueuse/shared";
339
340
const obj = reactive({
341
name: 'John',
342
age: 30,
343
email: 'john@example.com',
344
password: 'secret'
345
});
346
347
// Pick specific keys
348
const publicInfo = reactivePick(obj, 'name', 'email');
349
console.log(publicInfo); // { name: 'John', email: 'john@example.com' }
350
351
// Pick using predicate
352
const nameFields = reactivePick(obj, (value, key) => key.includes('name'));
353
```