Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const sidebar = {
'/guide/introduction',
'/guide/instance',
'/guide/template-syntax',
// '/guide/data-methods',
'/guide/data-methods',
'/guide/computed',
'/guide/class-and-style',
'/guide/conditional',
Expand Down
125 changes: 125 additions & 0 deletions src/guide/data-methods.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# データプロパティとメソッド

## データプロパティ

コンポーネントの `data` オプションは関数です。Vue は新しいコンポーネントのインスタンスを作成する際に、この関数を呼び出します。これはオブジェクトを返すもので、 Vue はオブジェクトをそのリアクティブシステムでラップして、コンポーネントのインスタンスに `$data` として格納します。便宜上、そのオブジェクトのトップレベルのプロパティは、コンポーネントのインスタンスを介して直接公開されます:

```js
const app = Vue.createApp({
data() {
return { count: 4 }
}
})

const vm = app.mount('#app')

console.log(vm.$data.count) // => 4
console.log(vm.count) // => 4

// vm.count に値を代入すると、 $data.count も更新
vm.count = 5
console.log(vm.$data.count) // => 5

// ... 逆もまた同様
vm.$data.count = 6
console.log(vm.count) // => 6
```

これらのインスタンスプロパティは、インスタンスの初回作成時にのみ追加されます。そのため、 `data` 関数から返されたオブジェクトに、それらがすべて含まれていることを確認する必要があります。必要に応じて、必要な値がまだ利用できないプロパティには、 `null` や `undefined` 、またはその他のプレースホルダーの値を使ってください。

新しいプロパティを `data` に含めずに、コンポーネントのインスタンスに直接追加することはできます。しかし、このプロパティはリアクティブな `$data` オブジェクトによって裏付けされていないので、 [Vue のリアクティブシステム](reactivity.html) によって、自動的に追跡されることはありません。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

backed by の訳ですが、ここでは 支援する 的な意味合いを持ったものだ思います。なので、以下な感じになると思います。

Suggested change
新しいプロパティを `data` に含めずに、コンポーネントのインスタンスに直接追加することはできます。しかし、このプロパティはリアクティブな `$data` オブジェクトによって裏付けされていないので[Vue のリアクティブシステム](reactivity.html) によって、自動的に追跡されることはありません。
新しいプロパティを `data` に含めずに、コンポーネントのインスタンスに直接追加することはできます。しかし、このプロパティはリアクティブな `$data` オブジェクトによって支援されていないので[Vue のリアクティブシステム](reactivity.html) によって、自動的に追跡されることはありません。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

そうですね。大きく2つの訳があって「裏付けされている」か「支持されている」のどちらか悩みました。
後者の訳にして「支えられている」ぐらいの簡単な日本語にしますね。


Vue は、コンポーネントのインスタンスを介して自身のビルトイン API を公開する際に、 `$` をプレフィックスに使います。 また、内部プロパティのために `_` を予約しています。トップレベルの `data` プロパティの名前に、これらの文字からはじまる名前を使うことは避けるべきです。

## メソッド

コンポーネントのインスタンスにメソッドを追加するには、 `methods` オプションを使います。これは必要なメソッドを含むオブジェクトでなければなりません:

```js
const app = Vue.createApp({
data() {
return { count: 4 }
},
methods: {
increment() {
// `this` はコンポーネントインスタンスを参照
this.count++
}
}
})

const vm = app.mount('#app')

console.log(vm.count) // => 4

vm.increment()

console.log(vm.count) // => 5
```

Vue は、 `methods` の `this` を自動的に束縛して、常にコンポーネントのインスタンスを参照します。これにより、メソッドがイベントリスナやコールバックとして使われる際に、正しい `this` の値を保持することができます。Vue が適切な `this` の値を束縛するのを防ぐため、 `methods` を定義する際にはアロー関数を使うのは避けるべきです。

コンポーネントのインスタンスの他のすべてのプロパティと同様に、 `methods` はコンポーネントのテンプレート内からアクセスできます。テンプレート内からはよくイベントリスナとして使われます:

```html
<button @click="increment">Up vote</button>
```

上の例では、 `<button>` がクリックされると、 `increment` メソッドが呼ばれます。

また、テンプレートから直接メソッドを呼び出すこともできます。後で説明しますが、通常は変わりに [算出プロパティ](computed.html) を使うのがよいです。しかし、メソッドを使うことは算出プロパティが実行可能なオプションではない場合に役に立ちます。テンプレートが JavaScript の式をサポートしていれば、どこでもメソッドを呼び出すことができます:
Copy link
Member Author

@naokie naokie Apr 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

computed properties aren't a viable option

いまいち伝わりづらい感じですが、直訳するしかできなかったです。
自分が技術的に通じてないだけかもしれませんが。


```html
<span :title="toTitleDate(date)">
{{ formatDate(date) }}
</span>
```

`toTitleDate` や `formatDate` メソッドがどれかリアクティブなデータにアクセスすると、あたかもテンプレートで直接使われていたかのように、それはレンダリングの依存関係として追跡されます。

テンプレートから呼び出されたメソッドは、データの変更や非同期処理の発火などの副作用があってはなりません。もしそのようなことをしたくなったら、代わりに [ライフサイクルフック](instance.html#lifecycle-hooks) を使うべきです。

### Debounce (デバウンス) と Throttle (スロットル)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

debounce も throttle も、カタカナ表記にしていることさえ、あまりなさそうですが…
見出しで並列表記しておきつつ、本文中ではカタカナにしてみました。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

おおいいですね! 👍

このケースのように、英語をベースに括弧付でカタカナを表記する場合は、以降では英語でいいと思います。ここで読者は読み方が分かって、以降は読めると思うので。


Vue は、 デバウンスやスロットルのサポートが組み込まれていませんが、 [Lodash](https://lodash.com/) などのライブラリを使って実装することができます。

コンポーネントが一度しか使われない場合には、 `methods` の中で直接デバウンスを適用することができます:

```html
<script src="https://unpkg.com/[email protected]/lodash.min.js"></script>
<script>
Vue.createApp({
methods: {
// Lodash によるデバウンス
click: _.debounce(function() {
// ... クリックに反応 ...
}, 500)
}
}).mount('#app')
</script>
```

しかし、この方法ではコンポーネントが再利用される場合に、すべてのコンポーネントが同じデバウンス関数を共有するため、問題が起きる可能性があります。コンポーネントのインスタンスをお互いに独立させるために、 `created` ライフサイクルフックにデバウンス関数を追加することができます:

```js
app.component('save-button', {
created() {
// Lodash によるデバウンス
this.debouncedClick = _.debounce(this.click, 500)
},
unmounted() {
// コンポーネントが削除されたらタイマーをキャンセル
this.debouncedClick.cancel()
},
methods: {
click() {
// ... クリックに反応 ...
}
},
template: `
<button @click="debouncedClick">
Save
</button>
`
})
```