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
@@ -14,7 +14,7 @@ With Options API, we use the `data` option to declare reactive state of a compon
14
14
exportdefault {
15
15
data() {
16
16
return {
17
-
count:1
17
+
count:0
18
18
}
19
19
},
20
20
@@ -159,10 +159,10 @@ Top-level imports and variables declared in `<script setup>` are automatically u
159
159
To add methods to a component instance we use the `methods` option. This should be an object containing the desired methods:
160
160
161
161
```js
162
-
constapp=Vue.createApp({
162
+
exportdefault{
163
163
data() {
164
164
return {
165
-
count:4
165
+
count:0
166
166
}
167
167
},
168
168
methods: {
@@ -174,20 +174,77 @@ const app = Vue.createApp({
174
174
// methods can be called in lifecycle hooks, or other methods!
175
175
this.increment()
176
176
}
177
-
})
177
+
}
178
178
```
179
179
180
+
[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdD5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgZGF0YSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgY291bnQ6IDBcbiAgICB9XG4gIH0sXG4gIG1ldGhvZHM6IHtcbiAgICBpbmNyZW1lbnQoKSB7XG4gICAgICB0aGlzLmNvdW50KytcbiAgICB9XG4gIH0sXG4gIG1vdW50ZWQoKSB7XG4gICAgdGhpcy5pbmNyZW1lbnQoKVxuICB9XG59XG48L3NjcmlwdD5cblxuPHRlbXBsYXRlPlxuICA8YnV0dG9uIEBjbGljaz1cImluY3JlbWVudFwiPnt7IGNvdW50IH19PC9idXR0b24+XG48L3RlbXBsYXRlPiIsImltcG9ydC1tYXAuanNvbiI6IntcbiAgXCJpbXBvcnRzXCI6IHtcbiAgICBcInZ1ZVwiOiBcImh0dHBzOi8vc2ZjLnZ1ZWpzLm9yZy92dWUucnVudGltZS5lc20tYnJvd3Nlci5qc1wiXG4gIH1cbn0ifQ==)
181
+
180
182
Vue automatically binds the `this` value for `methods` so that it always refers to the component instance. This ensures that a method retains the correct `this` value if it's used as an event listener or callback. You should avoid using arrow functions when defining `methods`, as that prevents Vue from binding the appropriate `this` value.
181
183
182
184
Just like all other properties of the component instance, the `methods` are accessible from within the component's template. Inside a template they are most commonly used as event listeners:
183
185
184
186
```vue-html
185
-
<button @click="increment">Up vote</button>
187
+
<button @click="increment">{{ count }}</button>
186
188
```
187
189
188
190
In the example above, the method `increment` will be called when the `<button>` is clicked.
189
191
190
-
It is also possible to call a method directly from a template. As we'll see shortly, it's usually better to use a [computed property](computed.html) instead. However, using a method can be useful in scenarios where computed properties aren't a viable option. You can call a method anywhere that a template supports JavaScript expressions:
192
+
</div>
193
+
194
+
<divclass="composition-api">
195
+
196
+
To declare methods when using Composition API, simply declare functions in the same scope with the reactive state:
197
+
198
+
```js
199
+
import { ref } from'vue'
200
+
201
+
exportdefault {
202
+
setup() {
203
+
constcount=ref(0)
204
+
205
+
functionincrement() {
206
+
count.value++
207
+
}
208
+
209
+
// when using manual setup(),
210
+
// don't forget to expose the function as well.
211
+
return {
212
+
count,
213
+
increment
214
+
}
215
+
}
216
+
}
217
+
```
218
+
219
+
Methods are typically used as event listeners:
220
+
221
+
```vue-html
222
+
<button @click="increment">{{ count }}</button>
223
+
```
224
+
225
+
Again, the same example is much simpler in an SFC with `<script setup>`, as functions are auto-exposes as well:
226
+
227
+
```vue
228
+
<script setup>
229
+
import { ref } from 'vue'
230
+
231
+
const count = ref(0)
232
+
233
+
function increment() {
234
+
count.value++
235
+
}
236
+
</script>
237
+
238
+
<template>
239
+
<button @click="increment">{{ count }}</button>
240
+
</template>
241
+
```
242
+
243
+
[Try it in the Playground](https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHNjcmlwdCBzZXR1cD5cbmltcG9ydCB7IHJlZiB9IGZyb20gJ3Z1ZSdcblxuY29uc3QgY291bnQgPSByZWYoMClcblxuZnVuY3Rpb24gaW5jcmVtZW50KCkge1xuICBjb3VudC52YWx1ZSsrXG59XG48L3NjcmlwdD5cblxuPHRlbXBsYXRlPlxuICA8YnV0dG9uIEBjbGljaz1cImluY3JlbWVudFwiPnt7IGNvdW50IH19PC9idXR0b24+XG48L3RlbXBsYXRlPiIsImltcG9ydC1tYXAuanNvbiI6IntcbiAgXCJpbXBvcnRzXCI6IHtcbiAgICBcInZ1ZVwiOiBcImh0dHBzOi8vc2ZjLnZ1ZWpzLm9yZy92dWUucnVudGltZS5lc20tYnJvd3Nlci5qc1wiXG4gIH1cbn0ifQ==)
244
+
245
+
</div>
246
+
247
+
It is also possible to call a method inside a binding expression. As we'll see shortly, it's usually better to use a [computed property](computed.html) instead. However, using a method can be useful in scenarios where computed properties aren't a viable option. You can call a method anywhere that a template supports JavaScript expressions:
191
248
192
249
```vue-html
193
250
<span :title="toTitleDate(date)">
@@ -199,6 +256,59 @@ If the methods `toTitleDate` or `formatDate` access any reactive data then it wi
199
256
200
257
Methods called inside binding expressions should **not** have any side effects, such as changing data or triggering asynchronous operations. If you find yourself tempted to do that you should probably use a [lifecycle hook](/guide/components/lifecycle.html) instead.
201
258
259
+
### Deep Reactivity
260
+
261
+
In Vue, state is deeply reactive by default. This means you can expect changes to be detected even when you mutate nested objects or arrays:
262
+
263
+
<divclass="options-api">
264
+
265
+
```js
266
+
exportdefault {
267
+
data() {
268
+
return {
269
+
obj: {
270
+
nested: { count:0 },
271
+
arr: ['foo', 'bar']
272
+
}
273
+
}
274
+
},
275
+
methods: {
276
+
mutateDeeply() {
277
+
// these will work as expected.
278
+
this.obj.nested.count++
279
+
this.obj.arr.push('baz')
280
+
}
281
+
}
282
+
}
283
+
```
284
+
285
+
</div>
286
+
287
+
<divclass="composition-api">
288
+
289
+
```vue
290
+
<script setup>
291
+
import { ref } from 'vue'
292
+
293
+
const obj = ref({
294
+
nested: { count: 0 },
295
+
arr: ['foo', 'bar']
296
+
})
297
+
298
+
function mutateDeeply() {
299
+
// these will work as expected.
300
+
obj.value.nested.count++
301
+
obj.value.arr.push('baz')
302
+
}
303
+
</script>
304
+
```
305
+
306
+
</div>
307
+
308
+
It is also possible to explicitly create ["shallow" reactive objects](/guide/advanced/reactivity-in-depth.html#deep-vs-shallow-reactivity) where the reactivity is only tracked for root-level properties, however they are typically only needed in advanced use cases.
309
+
310
+
<divclass="options-api">
311
+
202
312
### Debouncing and Throttling
203
313
204
314
Vue doesn't include built-in support for debouncing or throttling but it can be implemented using libraries such as [Lodash](https://lodash.com/).
To declare methods when using Composition API, simply declare functions in the same scope with the reactive state:
255
-
256
-
```js
257
-
import { ref } from'vue'
258
-
259
-
exportdefault {
260
-
setup() {
261
-
constcount=ref(0)
262
-
263
-
functionincrement() {
264
-
count.value++
265
-
}
266
-
267
-
// when using manual setup(),
268
-
// don't forget to expose the function as well.
269
-
return {
270
-
count,
271
-
increment
272
-
}
273
-
}
274
-
}
275
-
```
276
-
277
-
```html
278
-
<button@click="increment">{{ count }}</button>
279
-
```
280
-
281
-
Again, it's much simpler with `<script setup>` as it auto-exposes functions as well:
282
-
283
-
```vue
284
-
<script setup>
285
-
import { ref } from 'vue'
286
-
287
-
const count = ref(0)
288
-
289
-
function increment() {
290
-
count.value++
291
-
}
292
-
</script>
293
-
294
-
<template>
295
-
<button @click="increment">{{ count }}</button>
296
-
</template>
297
-
```
298
-
299
-
</div>
300
-
301
364
### Ref Transform
302
365
303
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:
@@ -319,3 +382,5 @@ function increment() {
319
382
:::warning Experimental
320
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).
Copy file name to clipboardExpand all lines: src/guide/essentials/computed.md
+19-1Lines changed: 19 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,8 +4,10 @@
4
4
5
5
In-template expressions are very convenient, but they are meant for simple operations. Putting too much logic in your templates can make them bloated and hard to maintain. For example, if we have an object with a nested array:
6
6
7
+
<divclass="options-api">
8
+
7
9
```js
8
-
Vue.createApp({
10
+
exportdefault{
9
11
data() {
10
12
return {
11
13
author: {
@@ -18,9 +20,25 @@ Vue.createApp({
18
20
}
19
21
}
20
22
}
23
+
}
24
+
```
25
+
26
+
</div>
27
+
<divclass="composition-api">
28
+
29
+
```js
30
+
constauthor=ref({
31
+
name:'John Doe',
32
+
books: [
33
+
'Vue 2 - Advanced Guide',
34
+
'Vue 3 - Basic Guide',
35
+
'Vue 4 - The Mystery'
36
+
]
21
37
})
22
38
```
23
39
40
+
</div>
41
+
24
42
And we want to display different messages depending on if `author` already has some books or not
0 commit comments