You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/guide/essentials/reactivity-fundamentals.md
+51-91Lines changed: 51 additions & 91 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -104,7 +104,7 @@ There are two reasons why we need to wrap the value in an object:
104
104
count.value++// this will affect the log output.
105
105
```
106
106
107
-
This capability is quite important as it unlocks powerful patterns that allow us to compose reactive logic encapsulated in decoupled functions, which we will discuss later in the guide.
107
+
This capability is quite important as it is frequently used when extracting logic into [Composable Functions](/guide/reusability/composables.html).
Reactive objects are [JavaScript Proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) and work exactly like normal objects. Calling `reactive()` on the same object always returns the same proxy, and calling `reactive()` on an existing proxy also returns that same proxy:
169
+
Reactive objects are [JavaScript Proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) and behave just like normal objects. Calling `reactive()` on the same object always returns the same proxy, and calling `reactive()` on an existing proxy also returns that same proxy:
When you create a ref with object value, it also implicitly converts the value to a proxy using `reactive()`:
@@ -183,14 +189,47 @@ const objRef = ref(raw)
183
189
console.log(objRef.value=== proxy) // true
184
190
```
185
191
186
-
It is important to note that the proxy is not equal to the original object. Only the proxy is reactive. Mutating the original object will not trigger reactive updates:
192
+
:::tip
193
+
The reactive proxy is NOT equal to the original object, and only the proxy is reactive. Mutating the original object will not trigger updates. The best practice when working with Vue's reactivity system is to **exclusively use the proxied versions of your state**.
194
+
:::
195
+
196
+
### Ref Unwrapping in Reactive Objects
197
+
198
+
When a `ref` is accessed or mutated as a property of a reactive object, it automatically unwraps to the inner value so it behaves like a normal property:
199
+
200
+
```js
201
+
constcount=ref(0)
202
+
conststate=reactive({
203
+
count
204
+
})
205
+
206
+
console.log(state.count) // 0
207
+
208
+
state.count=1
209
+
console.log(count.value) // 1
210
+
```
211
+
212
+
If a new ref is assigned to a property linked to an existing ref, it will replace the old ref:
187
213
188
214
```js
189
-
console.log(raw === proxy) // false
190
-
raw.count++// won't trigger updates!
215
+
constotherCount=ref(2)
216
+
217
+
state.count= otherCount
218
+
console.log(state.count) // 2
219
+
console.log(count.value) // 1
191
220
```
192
221
193
-
Therefore, the best practice when working with Vue's reactivity system is to **exclusively use the proxied versions of your state**.
222
+
Ref unwrapping only happens when nested inside a reactive object. There is no unwrapping performed when the ref is accessed from an array or a native collection type like [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map):
223
+
224
+
```js
225
+
constbooks=reactive([ref('Vue 3 Guide')])
226
+
// need .value here
227
+
console.log(books[0].value)
228
+
229
+
constmap=reactive(newMap([['count', ref(0)]]))
230
+
// need .value here
231
+
console.log(map.get('count').value)
232
+
```
194
233
195
234
</div>
196
235
@@ -330,24 +369,24 @@ export default {
330
369
331
370
```vue
332
371
<script setup>
333
-
import { ref } from 'vue'
372
+
import { reactive } from 'vue'
334
373
335
-
const obj = ref({
374
+
const obj = reactive({
336
375
nested: { count: 0 },
337
376
arr: ['foo', 'bar']
338
377
})
339
378
340
379
function mutateDeeply() {
341
380
// these will work as expected.
342
-
obj.value.nested.count++
343
-
obj.value.arr.push('baz')
381
+
obj.nested.count++
382
+
obj.arr.push('baz')
344
383
}
345
384
</script>
346
385
```
347
386
348
387
</div>
349
388
350
-
It is also possible to explicitly create ["shallow" refs and reactive objects](/api/reactivity-advanced.html#shallowref) where the reactivity is only tracked at the root-level, however they are typically only needed in advanced use cases.
389
+
It is also possible to explicitly create [shallow refs](<(/api/reactivity-advanced.html#shallowref)>) and [shallow reactive objects](/api/reactivity-advanced.html#shallowreactive) where the reactivity is only tracked at the root-level, however they are typically only needed in advanced use cases.
351
390
352
391
<divclass="options-api">
353
392
@@ -425,83 +464,4 @@ function increment() {
425
464
Ref transform is currently an experimental feature. It is disabled by default and requires [explicit opt-in](https://github.com/vuejs/rfcs/blob/ref-sugar-2/active-rfcs/0000-ref-sugar.md#enabling-the-macros). It may also change before being finalized. More details can be found in its [proposal and discussion on GitHub](https://github.com/vuejs/rfcs/discussions/369).
426
465
:::
427
466
428
-
## Additional Details
429
-
430
-
### Ref Unwrapping in Reactive Objects
431
-
432
-
When a `ref` is accessed or mutated as a property of a reactive object, it automatically unwraps to the inner value so it behaves like a normal property:
433
-
434
-
```js
435
-
constcount=ref(0)
436
-
conststate=reactive({
437
-
count
438
-
})
439
-
440
-
console.log(state.count) // 0
441
-
442
-
state.count=1
443
-
console.log(count.value) // 1
444
-
```
445
-
446
-
If a new ref is assigned to a property linked to an existing ref, it will replace the old ref:
447
-
448
-
```js
449
-
constotherCount=ref(2)
450
-
451
-
state.count= otherCount
452
-
console.log(state.count) // 2
453
-
console.log(count.value) // 1
454
-
```
455
-
456
-
Ref unwrapping only happens when nested inside a reactive object. There is no unwrapping performed when the ref is accessed from an array or a native collection type like [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map):
457
-
458
-
```js
459
-
constbooks=reactive([ref('Vue 3 Guide')])
460
-
// need .value here
461
-
console.log(books[0].value)
462
-
463
-
constmap=reactive(newMap([['count', ref(0)]]))
464
-
// need .value here
465
-
console.log(map.get('count').value)
466
-
```
467
-
468
-
### Destructuring Reactive Objects
469
-
470
-
When we want to use a few properties of the large reactive object, it could be tempting to use destructuring to get properties we want:
471
-
472
-
```js
473
-
import { reactive } from'vue'
474
-
475
-
constbook=reactive({
476
-
author:'Vue Team',
477
-
year:'2020',
478
-
title:'Vue 3 Guide',
479
-
description:'You are reading this book right now ;)',
480
-
price:'free'
481
-
})
482
-
483
-
let { author, title } = book
484
-
```
485
-
486
-
Unfortunately, with such a destructuring the reactivity for both properties would be lost. For such a case, we need to convert our reactive object to a set of refs. These refs will retain the reactive connection to the source object:
487
-
488
-
```js
489
-
import { reactive, toRefs } from'vue'
490
-
491
-
constbook=reactive({
492
-
author:'Vue Team',
493
-
year:'2020',
494
-
title:'Vue 3 Guide',
495
-
description:'You are reading this book right now ;)',
496
-
price:'free'
497
-
})
498
-
499
-
let { author, title } =toRefs(book)
500
-
501
-
title.value='Vue 3 Detailed Guide'// we need to use .value as title is a ref now
502
-
console.log(book.title) // 'Vue 3 Detailed Guide'
503
-
```
504
-
505
-
You can learn more about `toRefs` in the [API Reference](/api/reactivity-utilities.html#torefs).
When we want to use a few properties of the large reactive object, it could be tempting to use destructuring to get properties we want. However, the destructured property would lose the reactivity connection to the original object:
6
+
7
+
```js
8
+
conststate=reactive({
9
+
count:0
10
+
// ... with many other properties
11
+
})
12
+
13
+
// `count` won't be reactive once destructured
14
+
// as it's just a number now
15
+
const { count } = state
16
+
```
17
+
18
+
You can create a ref from a property of a reactive object with [`toRef()`](/api/reactivity-utilities.html#toref):
0 commit comments