Skip to content

Commit ff1d117

Browse files
committed
progress
1 parent 43a68fa commit ff1d117

File tree

4 files changed

+38
-18
lines changed

4 files changed

+38
-18
lines changed

src/.vitepress/config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ const sidebar = {
119119
link: '/guide/essentials/basic-reactivity'
120120
},
121121
{ text: 'Computed Properties', link: '/guide/essentials/computed' },
122-
{ text: 'Watchers and Effects', link: '/guide/essentials/watchers' },
122+
{ text: 'Watchers', link: '/guide/essentials/watchers' },
123123
{
124124
text: 'Class and Style Bindings',
125125
link: '/guide/essentials/class-and-style'

src/guide/essentials/basic-reactivity.md

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,15 @@ Vue uses a `$` prefix when exposing its own built-in APIs via the component inst
4747

4848
### Reactive Variables with `ref`
4949

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:
5151

5252
```js
5353
import { ref } from 'vue'
5454

5555
const count = ref(0)
5656
```
5757

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:
5959

6060
```js
6161
const count = ref(0)
@@ -150,6 +150,26 @@ Top-level imports and variables declared in `<script setup>` are automatically u
150150

151151
> 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.
152152
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.
172+
153173
</div>
154174

155175
## Declaring Methods
@@ -361,9 +381,9 @@ app.component('save-button', {
361381

362382
<div class="composition-api">
363383

364-
### Ref Transform
384+
### Ref Transform <Badge type="warning" text="experimental" />
365385

366-
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:
367387

368388
```vue
369389
<script setup>
@@ -379,8 +399,8 @@ function increment() {
379399
</template>
380400
```
381401

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).
384404
:::
385405

386406
</div>

src/guide/essentials/computed.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export default {
2727
<div class="composition-api">
2828

2929
```js
30-
const author = ref({
30+
const author = reactive({
3131
name: 'John Doe',
3232
books: [
3333
'Vue 2 - Advanced Guide',
@@ -95,9 +95,9 @@ You can data-bind to computed properties in templates just like a normal propert
9595

9696
```vue
9797
<script setup>
98-
import { ref, computed } from 'vue'
98+
import { reactive, computed } from 'vue'
9999
100-
const author = ref({
100+
const author = reactive({
101101
name: 'John Doe',
102102
books: [
103103
'Vue 2 - Advanced Guide',
@@ -108,7 +108,7 @@ const author = ref({
108108
109109
// a computed ref
110110
const publishedBooksMessage = computed(() => {
111-
return author.value.books.length > 0 ? 'Yes' : 'No'
111+
return author.books.length > 0 ? 'Yes' : 'No'
112112
})
113113
</script>
114114
@@ -118,11 +118,11 @@ const publishedBooksMessage = computed(() => {
118118
</template>
119119
```
120120

121-
[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==)
122122

123123
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.
124124

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.
126126

127127
</div>
128128

@@ -152,13 +152,13 @@ methods: {
152152
```js
153153
// in component
154154
function calculateBooksMessage() {
155-
return author.value.books.length > 0 ? 'Yes' : 'No'
155+
return author.books.length > 0 ? 'Yes' : 'No'
156156
}
157157
```
158158

159159
</div>
160160

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 <code class="options-api">author.books</code><code class="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.
162162

163163
This also means the following computed property will never update, because `Date.now()` is not a reactive dependency:
164164

@@ -188,7 +188,7 @@ Why do we need caching? Imagine we have an expensive computed property `list`, w
188188

189189
## Writable Computed
190190

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:
192192

193193
<div class="options-api">
194194

src/guide/essentials/watchers.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# Watchers and Effects
1+
# Watchers
22

3-
## Watchers
3+
## Basic Watchers
44

55
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.
66

0 commit comments

Comments
 (0)