0
# Reactive State
1
2
Core reactivity system providing reactive objects, refs, and readonly proxies with automatic dependency tracking. The reactivity system forms the foundation of Vue's composition API.
3
4
## Capabilities
5
6
### Reactive Objects
7
8
Creates a reactive proxy of an object where all nested properties become reactive and trigger updates when changed.
9
10
```typescript { .api }
11
/**
12
* Creates a reactive proxy of an object
13
* @param obj - Object to make reactive
14
* @returns Reactive proxy with unwrapped refs
15
*/
16
function reactive<T extends object>(obj: T): UnwrapRef<T>;
17
18
/**
19
* Creates a shallow reactive proxy where only root-level properties are reactive
20
* @param obj - Object to make shallow reactive
21
* @returns Shallow reactive proxy
22
*/
23
function shallowReactive<T extends object>(obj: T): T;
24
25
/**
26
* Checks if an object is reactive
27
* @param obj - Object to check
28
* @returns True if object is reactive
29
*/
30
function isReactive(obj: any): boolean;
31
```
32
33
**Usage Examples:**
34
35
```typescript
36
import { reactive, isReactive } from "@vue/composition-api";
37
38
// Basic reactive object
39
const state = reactive({
40
count: 0,
41
user: {
42
name: "Alice",
43
age: 25,
44
},
45
});
46
47
// All properties are reactive
48
state.count++; // Triggers reactivity
49
state.user.name = "Bob"; // Triggers reactivity
50
51
console.log(isReactive(state)); // true
52
```
53
54
### Refs
55
56
Creates a reactive reference to a value. Refs provide reactivity for primitive values and serve as reactive containers.
57
58
```typescript { .api }
59
/**
60
* Creates a reactive reference to a value
61
* @param value - Initial value
62
* @returns Reactive reference with .value property
63
*/
64
function ref<T>(value: T): Ref<UnwrapRef<T>>;
65
function ref<T = any>(): Ref<T | undefined>;
66
67
/**
68
* Creates a shallow reactive reference (nested objects are not reactive)
69
* @param value - Initial value
70
* @returns Shallow reactive reference
71
*/
72
function shallowRef<T>(value: T): Ref<T>;
73
function shallowRef<T = any>(): Ref<T | undefined>;
74
75
/**
76
* Checks if a value is a ref
77
* @param value - Value to check
78
* @returns True if value is a ref
79
*/
80
function isRef<T>(value: any): value is Ref<T>;
81
82
/**
83
* Returns the inner value of a ref, or the value itself if not a ref
84
* @param ref - Ref or value
85
* @returns Unwrapped value
86
*/
87
function unref<T>(ref: T | Ref<T>): T;
88
89
/**
90
* Manually triggers effects for a shallow ref
91
* @param ref - Ref to trigger
92
*/
93
function triggerRef(ref: Ref<any>): void;
94
```
95
96
**Usage Examples:**
97
98
```typescript
99
import { ref, isRef, unref, triggerRef } from "@vue/composition-api";
100
101
// Basic ref usage
102
const count = ref(0);
103
const name = ref("Alice");
104
105
console.log(count.value); // 0
106
count.value++; // Triggers reactivity
107
108
// Type-safe operations
109
console.log(isRef(count)); // true
110
console.log(unref(count)); // Current value without .value access
111
112
// Shallow ref for performance
113
const expensiveData = shallowRef({ large: "object" });
114
// Manually trigger when you modify nested properties
115
triggerRef(expensiveData);
116
```
117
118
### Ref Conversions
119
120
Utilities for converting between refs and reactive objects.
121
122
```typescript { .api }
123
/**
124
* Converts all properties of an object to refs
125
* @param obj - Reactive object
126
* @returns Object with all properties as refs
127
*/
128
function toRefs<T extends object>(obj: T): ToRefs<T>;
129
130
/**
131
* Creates a ref to a property of a reactive object
132
* @param object - Source reactive object
133
* @param key - Property key
134
* @returns Ref linked to the property
135
*/
136
function toRef<T extends object, K extends keyof T>(
137
object: T,
138
key: K
139
): Ref<T[K]>;
140
141
/**
142
* Creates a ref with custom getter and setter functions
143
* @param factory - Factory function returning getter/setter
144
* @returns Custom ref
145
*/
146
function customRef<T>(factory: CustomRefFactory<T>): Ref<T>;
147
148
/**
149
* Internal function to create a ref with specific options (low-level API)
150
* @param options - Ref options with get/set functions
151
* @param isReadonly - Whether the ref should be readonly
152
* @param isComputed - Whether this is a computed ref
153
* @returns Created ref instance
154
*/
155
function createRef<T>(
156
options: RefOption<T>,
157
isReadonly?: boolean,
158
isComputed?: boolean
159
): Ref<T>;
160
161
/**
162
* Proxies an object to automatically unwrap refs in properties
163
* @param objectWithRefs - Object containing refs
164
* @returns Proxied object with auto-unwrapped refs
165
*/
166
function proxyRefs<T extends object>(objectWithRefs: T): ShallowUnwrapRef<T>;
167
```
168
169
**Usage Examples:**
170
171
```typescript
172
import { reactive, toRefs, toRef, customRef } from "@vue/composition-api";
173
174
// Convert reactive object to refs
175
const state = reactive({ count: 0, name: "Alice" });
176
const { count, name } = toRefs(state);
177
178
// Now count and name are refs
179
count.value++; // Updates state.count
180
181
// Create ref to specific property
182
const user = reactive({ profile: { name: "Bob" } });
183
const nameRef = toRef(user.profile, "name");
184
185
// Custom ref with debouncing
186
function useDebouncedRef(value: string, delay = 200) {
187
let timeout: NodeJS.Timeout;
188
return customRef((track, trigger) => ({
189
get() {
190
track();
191
return value;
192
},
193
set(newValue: string) {
194
clearTimeout(timeout);
195
timeout = setTimeout(() => {
196
value = newValue;
197
trigger();
198
}, delay);
199
},
200
}));
201
}
202
```
203
204
### Readonly State
205
206
Creates readonly proxies that prevent mutations while maintaining reactivity for reading.
207
208
```typescript { .api }
209
/**
210
* Creates a deep readonly proxy of an object
211
* @param obj - Object to make readonly
212
* @returns Deep readonly proxy
213
*/
214
function readonly<T extends object>(obj: T): DeepReadonly<UnwrapNestedRefs<T>>;
215
216
/**
217
* Creates a shallow readonly proxy (only root level is readonly)
218
* @param obj - Object to make shallow readonly
219
* @returns Shallow readonly proxy
220
*/
221
function shallowReadonly<T extends object>(obj: T): Readonly<T>;
222
223
/**
224
* Checks if an object is readonly
225
* @param obj - Object to check
226
* @returns True if object is readonly
227
*/
228
function isReadonly(obj: any): boolean;
229
```
230
231
**Usage Examples:**
232
233
```typescript
234
import { reactive, readonly, isReadonly } from "@vue/composition-api";
235
236
const state = reactive({ count: 0, nested: { value: 1 } });
237
const readonlyState = readonly(state);
238
239
console.log(readonlyState.count); // 0 (can read)
240
// readonlyState.count++; // TypeError in development
241
242
console.log(isReadonly(readonlyState)); // true
243
```
244
245
### Raw Object Access
246
247
Utilities for accessing the original non-reactive objects from reactive proxies.
248
249
```typescript { .api }
250
/**
251
* Returns the raw original object from a reactive proxy
252
* @param observed - Reactive object
253
* @returns Original non-reactive object
254
*/
255
function toRaw<T>(observed: T): T;
256
257
/**
258
* Marks an object to prevent it from being made reactive
259
* @param obj - Object to mark as raw
260
* @returns The same object, marked as raw
261
*/
262
function markRaw<T extends object>(obj: T): T;
263
264
/**
265
* Checks if an object is raw (not reactive)
266
* @param obj - Object to check
267
* @returns True if object is raw
268
*/
269
function isRaw(obj: any): boolean;
270
```
271
272
**Usage Examples:**
273
274
```typescript
275
import { reactive, toRaw, markRaw, isRaw } from "@vue/composition-api";
276
277
const original = { count: 0 };
278
const state = reactive(original);
279
280
console.log(toRaw(state) === original); // true
281
282
// Prevent object from becoming reactive
283
const nonReactive = markRaw({ data: "important" });
284
const attempted = reactive(nonReactive);
285
console.log(isRaw(attempted)); // true (reactivity was prevented)
286
```
287
288
### Vue 2 Compatibility Utilities
289
290
Vue 2 specific utilities for reactive operations.
291
292
```typescript { .api }
293
/**
294
* Reactive set utility (equivalent to Vue.set)
295
* @param target - Target object or array
296
* @param key - Property key or array index
297
* @param value - Value to set
298
*/
299
function set<T>(target: any, key: any, value: T): T;
300
301
/**
302
* Reactive delete utility (equivalent to Vue.delete)
303
* @param target - Target object or array
304
* @param key - Property key or array index
305
*/
306
function del(target: any, key: any): void;
307
```
308
309
**Usage Examples:**
310
311
```typescript
312
import { reactive, set, del } from "@vue/composition-api";
313
314
const state = reactive<{ [key: string]: any }>({});
315
316
// Add reactive property (needed in Vue 2)
317
set(state, "newProp", "value");
318
319
// Delete reactive property
320
del(state, "newProp");
321
```
322
323
## Types
324
325
```typescript { .api }
326
interface Ref<T = any> {
327
value: T;
328
}
329
330
interface ComputedRef<T = any> extends WritableComputedRef<T> {
331
readonly value: T;
332
}
333
334
interface WritableComputedRef<T> extends Ref<T> {
335
readonly effect: ReactiveEffect<T>;
336
}
337
338
type ToRefs<T = any> = { [K in keyof T]: Ref<T[K]> };
339
340
type UnwrapRef<T> = T extends Ref<infer V>
341
? UnwrapRefSimple<V>
342
: UnwrapRefSimple<T>;
343
344
type UnwrapRefSimple<T> = T extends
345
| Function
346
| CollectionTypes
347
| BaseTypes
348
| Ref
349
| RefUnwrapBailTypes[keyof RefUnwrapBailTypes]
350
? T
351
: T extends Array<any>
352
? { [K in keyof T]: UnwrapRefSimple<T[K]> }
353
: T extends object
354
? UnwrappedObject<T>
355
: T;
356
357
type ShallowUnwrapRef<T> = {
358
[K in keyof T]: T[K] extends Ref<infer V> ? V : T[K];
359
};
360
361
type DeepReadonly<T> = T extends Primitive
362
? T
363
: T extends Function
364
? T
365
: T extends Array<infer U>
366
? DeepReadonlyArray<U>
367
: DeepReadonlyObject<T>;
368
369
type UnwrapNestedRefs<T> = T extends Ref ? T : UnwrapRefSimple<T>;
370
371
type CustomRefFactory<T> = (
372
track: () => void,
373
trigger: () => void
374
) => {
375
get: () => T;
376
set: (value: T) => void;
377
};
378
379
interface RefOption<T> {
380
get(): T;
381
set?(value: T): void;
382
}
383
```