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/basic-reactivity.md
+26-6Lines changed: 26 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -47,15 +47,15 @@ Vue uses a `$` prefix when exposing its own built-in APIs via the component inst
47
47
48
48
### Reactive Variables with `ref`
49
49
50
-
The primary API for declaring reactive state when using Composition API is the `ref` method:
50
+
The primary API for declaring reactive state when using Composition API is the [`ref()`](/api/reactivity-core.html#ref) method:
51
51
52
52
```js
53
53
import { ref } from'vue'
54
54
55
55
constcount=ref(0)
56
56
```
57
57
58
-
`ref` takes the argument and returns it wrapped within an object with a `value` property, which can then be used to access or mutate the value of the reactive variable:
58
+
`ref` takes the argument and returns it wrapped within an object with a `.value` property, which can then be used to access or mutate the value of the reactive variable:
59
59
60
60
```js
61
61
constcount=ref(0)
@@ -150,6 +150,26 @@ Top-level imports and variables declared in `<script setup>` are automatically u
150
150
151
151
> For the rest of the guide, we will be primarily using SFC + `<script setup>` syntax for Composition API code examples, as that is the most common usage for Vue developers.
152
152
153
+
### Reactive Objects with `reactive`
154
+
155
+
It is also possible to directly create a reactive object or array with the [`reactive()`](/api/reactivity-core.html#reactive) method:
156
+
157
+
```vue
158
+
<script setup>
159
+
import { reactive } from 'vue'
160
+
161
+
const state = reactive({ count: 0 })
162
+
</script>
163
+
164
+
<template>
165
+
{{ state.count }}
166
+
</template>
167
+
```
168
+
169
+
Reactive objects are [JavaScript Proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) and work exactly like normal objects. When you create a ref with an object value, it also calls `reactive()` on that object internally.
170
+
171
+
Note that `reactive()` cannot hold primitive value types, and lacks the ability to "replace" the entire object with a new one. You **can** mix `ref()` and `reactive()` usage, however for consistency, we recommend using `ref()` unless you know you never intend to replace the object.
The necessity of using `.value`wit refs roots from the language constraints of JavaScript. However, with compile-time transforms we can improve the ergonomics by automatically appending `.value` in appropriate locations. The [ref transform](https://github.com/vuejs/vue-next/tree/master/packages/ref-transform) allows us to write the above example like this:
386
+
Refs require the `.value`property due to the language constraints of JavaScript. However, with compile-time transforms we can improve the ergonomics by automatically appending `.value` in appropriate locations. The [ref transform](https://github.com/vuejs/vue-next/tree/master/packages/ref-transform) allows us to write the above example like this:
367
387
368
388
```vue
369
389
<script setup>
@@ -379,8 +399,8 @@ function increment() {
379
399
</template>
380
400
```
381
401
382
-
:::warning Experimental
383
-
Ref transform is currently an experimental feature. It is disabled by default and requires explicit opt-in. 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).
402
+
:::warning Experimental Feature
403
+
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).
[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdCBzZXR1cD5cbmltcG9ydCB7IHJlZiwgY29tcHV0ZWQgfSBmcm9tICd2dWUnXG5cbmNvbnN0IGF1dGhvciA9IHJlZih7XG4gIG5hbWU6ICdKb2huIERvZScsXG4gIGJvb2tzOiBbXG4gICAgJ1Z1ZSAyIC0gQWR2YW5jZWQgR3VpZGUnLFxuICAgICdWdWUgMyAtIEJhc2ljIEd1aWRlJyxcbiAgICAnVnVlIDQgLSBUaGUgTXlzdGVyeSdcbiAgXVxufSlcblxuLy8gYSBjb21wdXRlZCByZWZcbmNvbnN0IHB1Ymxpc2hlZEJvb2tzTWVzc2FnZSA9IGNvbXB1dGVkKCgpID0+IHtcbiAgcmV0dXJuIGF1dGhvci52YWx1ZS5ib29rcy5sZW5ndGggPiAwID8gJ1llcycgOiAnTm8nXG59KVxuPC9zY3JpcHQ+XG5cbjx0ZW1wbGF0ZT5cbiAgPHA+SGFzIHB1Ymxpc2hlZCBib29rczo8L3A+XG4gIDxzcGFuPnt7IHB1Ymxpc2hlZEJvb2tzTWVzc2FnZSB9fTwvc3Bhbj5cbjwvdGVtcGxhdGU+IiwiaW1wb3J0LW1hcC5qc29uIjoie1xuICBcImltcG9ydHNcIjoge1xuICAgIFwidnVlXCI6IFwiaHR0cHM6Ly9zZmMudnVlanMub3JnL3Z1ZS5ydW50aW1lLmVzbS1icm93c2VyLmpzXCJcbiAgfVxufSJ9)
121
+
[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdCBzZXR1cD5cbmltcG9ydCB7IHJlYWN0aXZlLCBjb21wdXRlZCB9IGZyb20gJ3Z1ZSdcblxuY29uc3QgYXV0aG9yID0gcmVhY3RpdmUoe1xuICBuYW1lOiAnSm9obiBEb2UnLFxuICBib29rczogW1xuICAgICdWdWUgMiAtIEFkdmFuY2VkIEd1aWRlJyxcbiAgICAnVnVlIDMgLSBCYXNpYyBHdWlkZScsXG4gICAgJ1Z1ZSA0IC0gVGhlIE15c3RlcnknXG4gIF1cbn0pXG5cbi8vIGEgY29tcHV0ZWQgcmVmXG5jb25zdCBwdWJsaXNoZWRCb29rc01lc3NhZ2UgPSBjb21wdXRlZCgoKSA9PiB7XG4gIHJldHVybiBhdXRob3IuYm9va3MubGVuZ3RoID4gMCA/ICdZZXMnIDogJ05vJ1xufSlcbjwvc2NyaXB0PlxuXG48dGVtcGxhdGU+XG4gIDxwPkhhcyBwdWJsaXNoZWQgYm9va3M6PC9wPlxuICA8c3Bhbj57eyBwdWJsaXNoZWRCb29rc01lc3NhZ2UgfX08L3NwYW4+XG48L3RlbXBsYXRlPiIsImltcG9ydC1tYXAuanNvbiI6IntcbiAgXCJpbXBvcnRzXCI6IHtcbiAgICBcInZ1ZVwiOiBcImh0dHBzOi8vc2ZjLnZ1ZWpzLm9yZy92dWUucnVudGltZS5lc20tYnJvd3Nlci5qc1wiXG4gIH1cbn0ifQ==)
122
122
123
123
Here we have declared a computed property `publishedBooksMessage`. The `computed()` method expects a getter function, and returned value is a **computed ref**. Similar to normal refs, you can access the computed result as `publishedBooksMessage.value`. Computed refs are also auto-unwrapped in templates so you can reference them without `.value` in template expressions.
124
124
125
-
Vue is aware that the computation of `publishedBooksMessage` depends on `author.value.books`, so it will update any bindings that depend on `publishedBooksMessage` when `author.value.books` changes. And the best part is that we've created this dependency relationship declaratively: the computed getter function has no side effects, which makes it easier to test and understand.
125
+
Vue is aware that the computation of `publishedBooksMessage` depends on `author.books`, so it will update any bindings that depend on `publishedBooksMessage` when `author.books` changes. And the best part is that we've created this dependency relationship declaratively: the computed getter function has no side effects, which makes it easier to test and understand.
126
126
127
127
</div>
128
128
@@ -152,13 +152,13 @@ methods: {
152
152
```js
153
153
// in component
154
154
functioncalculateBooksMessage() {
155
-
returnauthor.value.books.length>0?'Yes':'No'
155
+
returnauthor.books.length>0?'Yes':'No'
156
156
}
157
157
```
158
158
159
159
</div>
160
160
161
-
Instead of a computed property, we can define the same function as a method. For the end result, the two approaches are indeed exactly the same. However, the difference is that **computed properties are cached based on their reactive dependencies.** A computed property will only re-evaluate when some of its reactive dependencies have changed. This means as long as <codeclass="options-api">author.books</code><codeclass="composition-api">author.value.books</code> has not changed, multiple access to `publishedBooksMessage` will immediately return the previously computed result without having to run the getter function again.
161
+
Instead of a computed property, we can define the same function as a method. For the end result, the two approaches are indeed exactly the same. However, the difference is that **computed properties are cached based on their reactive dependencies.** A computed property will only re-evaluate when some of its reactive dependencies have changed. This means as long as `author.books` has not changed, multiple access to `publishedBooksMessage` will immediately return the previously computed result without having to run the getter function again.
162
162
163
163
This also means the following computed property will never update, because `Date.now()` is not a reactive dependency:
164
164
@@ -188,7 +188,7 @@ Why do we need caching? Imagine we have an expensive computed property `list`, w
188
188
189
189
## Writable Computed
190
190
191
-
Computed properties are by default getter-only. When you attempt to mutate a computed property, you will receive a runtime warning. But you can provide a setter to create a "writable" computed property if you need to:
191
+
Computed properties are by default getter-only. When you attempt to mutate a computed property, you will receive a runtime warning. In the rare cases where you need a "writable" computed property, you can create one by providing both a getter and a setter:
Copy file name to clipboardExpand all lines: src/guide/essentials/watchers.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
-
# Watchers and Effects
1
+
# Watchers
2
2
3
-
## Watchers
3
+
## Basic Watchers
4
4
5
5
While computed properties are more appropriate in most cases, there are times when a custom watcher is necessary. That's why Vue provides a more generic way to react to data changes through the `watch` option. This is most useful when you want to perform asynchronous or expensive operations in response to changing data.
0 commit comments