Skip to content

Commit ace2812

Browse files
authored
Guide > Advanced Guides > Reactivity > Computed and Watch の翻訳を追従 (#315)
* docs: update watch behavior adjustments vuejs/docs@190ab87#diff-89664ba2a61a56095e5fec5ed2bc4fa5be629e0beda5bc25262d76b9cbcbe1eb * docs: more tweaks on watch flush timing vuejs/docs@bb8dac4#diff-89664ba2a61a56095e5fec5ed2bc4fa5be629e0beda5bc25262d76b9cbcbe1eb * Editorial Fixes vuejs/docs@23c4360#diff-89664ba2a61a56095e5fec5ed2bc4fa5be629e0beda5bc25262d76b9cbcbe1eb * docs: addng documentation for watch and proxied objects vuejs/docs@6ff094a#diff-89664ba2a61a56095e5fec5ed2bc4fa5be629e0beda5bc25262d76b9cbcbe1eb * Document why watched template refs require theflush: 'post' option to be set vuejs/docs@efbbe59#diff-89664ba2a61a56095e5fec5ed2bc4fa5be629e0beda5bc25262d76b9cbcbe1eb * docs: translate reactivity computed and watchers page
1 parent 3e3402d commit ace2812

File tree

1 file changed

+105
-36
lines changed

1 file changed

+105
-36
lines changed

src/guide/reactivity-computed-watchers.md

Lines changed: 105 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
## 算出プロパティ
66

7-
開発中に、他の状態に依存した状態が必要となることがあります。Vue では、これをコンポーネントの[算出プロパティ](computed.html#computed-properties)として処理します。算出プロパティの作成には、getter 関数を受け取り、関数の返り値に対して、イミュータブルでリアクティブな [ref](./reactivity-fundamentals.html#独立したリアクティブな値を-参照-として作成する) オブジェクトを返却する `computed` メソッドを利用します
7+
開発中に、他の状態に依存した状態が必要となることがあります。Vue では、これをコンポーネントの [算出プロパティ](computed.html#算出プロパティ) として処理します。算出プロパティの作成には、getter 関数を受け取り、関数の返り値に対して、イミュータブルでリアクティブな [ref](./reactivity-fundamentals.html#独立したリアクティブな値を-ref-として作成する) オブジェクトを返却する `computed` メソッドを利用します。
88

99
```js
1010
const count = ref(1)
@@ -48,7 +48,7 @@ setTimeout(() => {
4848

4949
### 監視の停止
5050

51-
`watchEffect` をコンポーネントの [setup()](composition-api-setup.html) 関数または[ライフサイクルフック](composition-api-lifecycle-hooks.html)の中で呼び出すと、ウォッチャはコンポーネントのライフサイクルにリンクされ、コンポーネントのアンマウント時に自動的に監視が停止します。
51+
`watchEffect` をコンポーネントの [setup()](composition-api-setup.html) 関数または [ライフサイクルフック](composition-api-lifecycle-hooks.html) の中で呼び出すと、ウォッチャはコンポーネントのライフサイクルにリンクされ、コンポーネントのアンマウント時に自動的に監視が停止します。
5252

5353
その他のケースのため、明示的にウォッチャによる監視を停止するための stop ハンドルが返されます:
5454

@@ -63,10 +63,10 @@ stop()
6363

6464
### 副作用の無効化
6565

66-
ウォッチされている関数は、それが無効化された時(つまりは、該当の作用が完了する前に状態が変化した時)にクリーンアップする必要のある非同期の関数を実行することがあります。 watchEffect による関数は、コールバックを無効化するための `onInvalidate` 関数を受け取ることができます。この関数は以下の場合に呼び出されます:
66+
ウォッチされている関数は、それが無効化された時つまりは、該当の作用が完了する前に状態が変化した時にクリーンアップする必要のある非同期の関数を実行することがあります。 watchEffect による関数は、コールバックを無効化するための `onInvalidate` 関数を受け取ることができます。この関数は以下の場合に呼び出されます:
6767

6868
- 該当の作用が再度実行された場合
69-
- ウォッチャが停止した場合 (例: `setup()` またはライフサイクルフックの中で `watchEffect` が使用されているコンポーネントがアンマウントされた時)
69+
- ウォッチャが停止した場合例: `setup()` またはライフサイクルフックの中で `watchEffect` が使用されているコンポーネントがアンマウントされた時
7070

7171
```js
7272
watchEffect(onInvalidate => {
@@ -78,12 +78,13 @@ watchEffect(onInvalidate => {
7878
})
7979
})
8080
```
81-
無効化するコールバックを直接返すのではなく、 `onInvalidate` 関数のコールバックを経由して登録しているのは、非同期のエラー処理では、返り値が非常に重要であるためです。データ取得を行う時、作用となる関数が非同期であることは非常に一般的なことです:
81+
82+
無効化するコールバックを直接返すのではなく、 `onInvalidate` 関数のコールバックを経由して登録しているのは、非同期のエラー処理では、返り値が非常に重要だからです。データ取得を行う時、作用となる関数が非同期であることは非常に一般的なことです:
8283

8384
```js
8485
const data = ref(null)
85-
watchEffect(async onInvalidate => {
86-
onInvalidate(() => {...}) // Promise の解決前にクリーンアップする関数を登録
86+
watchEffect(async (onInvalidate) => {
87+
onInvalidate(() => {/* ... */}) // Promise の解決前にクリーンアップする関数を登録
8788
data.value = await fetchData(props.id)
8889
})
8990
```
@@ -92,9 +93,10 @@ watchEffect(async onInvalidate => {
9293

9394
### 作用フラッシュのタイミング
9495

95-
Vue のリアクティブシステムは、無効になった変更をバッファリングし、非同期に処理することによって、おなじ "tick" の中での複数の状態の変化に対して、不要な重複の呼び出しを避けることができています。内部的には、コンポーネントの `update` 関数も、監視されている作用の一つです。ユーザーによる作用がキューに入っている場合、それは常に、他の全てのコンポーネントの更新の後に呼び出されます:
96+
Vue のリアクティブシステムは、無効になった変更をバッファリングし、非同期に処理することによって、おなじ "tick" の中での複数の状態の変化に対して、不要な重複の呼び出しを避けることができています。内部的には、コンポーネントの `update` 関数も、監視されている作用の 1 つです。ユーザーによる作用がキューに入っている場合、デフォルトではすべてのコンポーネントの更新の **前に** 呼び出されます:
9697

9798
```html
99+
98100
<template>
99101
<div>{{ count }}</div>
100102
</template>
@@ -119,42 +121,26 @@ Vue のリアクティブシステムは、無効になった変更をバッフ
119121
この例では:
120122

121123
- count は最初の実行時に同期的に記録されます。
122-
- `count` が変化した時、コンポーネントの**変更後**にコールバック関数が実行されます。
124+
- `count` が変化した時、コンポーネントの **変更前** にコールバック関数が実行されます。
123125

124-
初回実行は、コンポーネントがマウントされる前に実行されることに注意してください。そのため、作用の中で DOM(またはテンプレートの ref)へとアクセスしたい場合は、 `onMounted` フック内にて実行してください:
126+
コンポーネントの **更新後に** ウォッチャの作用を再実行する必要がある場合(例: [テンプレート参照](./composition-api-template-refs.md#テンプレート参照の監視) を使っている場合など)、追加の `options` オブジェクトを `flush` オプション(デフォルトは `'pre'`)と一緒に渡すことができます:
125127

126128
```js
127-
onMounted(() => {
128-
watchEffect(() => {
129-
// DOM やテンプレートの ref へのアクセス処理
130-
})
131-
})
132-
```
133-
134-
ウォッチャの作用を同期的に、またはコンポーネントの更新前に再実行したい場合は、 `flush` オプション(デフォルト値は `'post'`)によって、追加 `options` オブジェクトとして渡すことができます:
135-
136-
```js
137-
// 同時に発火
138-
watchEffect(
139-
() => {
140-
/* ... */
141-
},
142-
{
143-
flush: 'sync'
144-
}
145-
)
146-
147-
// コンポーネントの更新前に発火
129+
// コンポーネントが更新された後に発火、更新された DOM にアクセスできる
130+
// Note: これにより、コンポーネントの最初のレンダリングが終了するまで、
131+
// 作用の初期実行も延期される。
148132
watchEffect(
149133
() => {
150134
/* ... */
151135
},
152136
{
153-
flush: 'pre'
137+
flush: 'post'
154138
}
155139
)
156140
```
157141

142+
`flush` オプションは `'sync'` も指定できます。これは作用をいつも同期的に発火することを強制します。しかし、これは非効率的であって、ほとんど必要ないでしょう。
143+
158144
### Watcher のデバッグ
159145

160146
`onTrack` および `onTrigger` オプションは、ウォッチャの振る舞いのデバッグに利用できます。
@@ -181,7 +167,7 @@ watchEffect(
181167

182168
## `watch`
183169

184-
`watch` API は、コンポーネントの[watch](computed.html#watchers) プロパティと完全に同じものです。`watch` は特定のデータソースを監視し、別のコールバック関数内で副作用を適用する必要があります。また、デフォルトでは lazy となっています(つまり、監視しているデータソースが変更された場合に限り、コールバック関数が実行されます)
170+
`watch` API は、コンポーネントの [watch](computed.html#ウォッチャ) プロパティと完全に同じものです。`watch` は特定のデータソースを監視し、別のコールバック関数内で副作用を適用する必要があります。また、デフォルトでは lazy となっていますつまり、監視しているデータソースが変更された場合に限り、コールバック関数が実行されます
185171

186172
- [watchEffect](#watcheffect) と比較して、 `watch` は以下を可能とします:
187173

@@ -215,11 +201,94 @@ watch(count, (count, prevCount) => {
215201
ウォッチャは、配列を利用することで、複数のデータソースを同時に監視できます:
216202

217203
```js
218-
watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => {
219-
/* ... */
204+
const firstName = ref('');
205+
const lastName = ref('');
206+
207+
watch([firstName, lastName], (newValues, prevValues) => {
208+
console.log(newValues, prevValues);
220209
})
210+
211+
firstName.value = "John"; // logs: ["John",""] ["", ""]
212+
lastName.value = "Smith"; // logs: ["John", "Smith"] ["John", ""]
213+
```
214+
215+
### リアクティブなオブジェクトの監視
216+
217+
ウォッチャを使って、リアクティブな配列やオブジェクトの値を比較するには、値だけのコピーを作っておく必要があります。
218+
219+
```js
220+
const numbers = reactive([1, 2, 3, 4])
221+
222+
watch(
223+
() => [...numbers],
224+
(numbers, prevNumbers) => {
225+
console.log(numbers, prevNumbers);
226+
})
227+
228+
numbers.push(5) // logs: [1,2,3,4,5] [1,2,3,4]
229+
```
230+
231+
深くネストしたオブジェクトや配列のプロパティの変更をチェックするには、やはり `deep` オプションを true にする必要があります:
232+
233+
```js
234+
const state = reactive({
235+
id: 1,
236+
attributes: {
237+
name: "",
238+
},
239+
});
240+
241+
watch(
242+
() => state,
243+
(state, prevState) => {
244+
console.log(
245+
"not deep ",
246+
state.attributes.name,
247+
prevState.attributes.name
248+
);
249+
}
250+
);
251+
252+
watch(
253+
() => state,
254+
(state, prevState) => {
255+
console.log(
256+
"deep ",
257+
state.attributes.name,
258+
prevState.attributes.name
259+
);
260+
},
261+
{ deep: true }
262+
);
263+
264+
state.attributes.name = "Alex"; // Logs: "deep " "Alex" "Alex"
265+
```
266+
267+
しかし、リアクティブなオブジェクトや配列を監視すると、そのオブジェクトの状態の現在値と前回値の両方について参照が常に返されます。深くネストされたオブジェクトや配列を完全に監視するためには、値のディープコピーが必要な場合があります。これは [lodash.cloneDeep](https://lodash.com/docs/4.17.15#cloneDeep) のようなユーティリティで実現できます。
268+
269+
```js
270+
import _ from 'lodash';
271+
272+
const state = reactive({
273+
id: 1,
274+
attributes: {
275+
name: "",
276+
},
277+
});
278+
279+
watch(
280+
() => _.cloneDeep(state),
281+
(state, prevState) => {
282+
console.log(
283+
state.attributes.name,
284+
prevState.attributes.name
285+
);
286+
}
287+
);
288+
289+
state.attributes.name = "Alex"; // Logs: "Alex" ""
221290
```
222291

223292
### `watchEffect` との振る舞いの共有
224293

225-
`watch`[明示的な停止](#stopping-the-watcher)[副作用の無効化](#side-effect-invalidation) (代わりに第三引数に `onInvalidate` を渡すことになります)[作用フラッシュのタイミング](#effect-flush-timing)ならびに[デバッグ手法](#watcher-debugging)についての挙動を[`watchEffect`](#watcheffect)と共有しています。
294+
`watch` [明示的な停止](#監視の停止)[副作用の無効化](#副作用の無効化)代わりに第三引数に `onInvalidate` を渡すことになります[作用フラッシュのタイミング](#作用フラッシュのタイミング) ならびに [デバッグ手法](#watcher-のデバッグ) についての挙動を [`watchEffect`](#watcheffect) と共有しています。

0 commit comments

Comments
 (0)