Skip to content

Guide > Component Basics の翻訳を追従 #281

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 27, 2021
Merged
Changes from all 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
54 changes: 27 additions & 27 deletions src/guide/component-basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ app.mount('#components-demo')

<common-codepen-snippet title="Component basics" slug="abORVEJ" tab="js,result" :preview="false" />

コンポーネントは再利用可能なインスタンスなので、`data`、 `computed`、 `watch`、 `methods`、そしてライフサイクルフックのようなルートインスタンスと同様のオプションが利用可能です。唯一の例外は `el` のようなルート固有のオプションです。
コンポーネントは再利用可能なインスタンスなので、`data`、 `computed`、 `watch`、 `methods`、そしてライフサイクルフックのようなルートインスタンスと同様のオプションが利用可能です。

## コンポーネントの再利用

Expand All @@ -66,7 +66,7 @@ app.mount('#components-demo')

例えば、 ヘッダー、サイドバー、コンテンツエリアなどのコンポーネントがあり、それぞれには一般的にナビゲーションリンクやブログ投稿などのコンポーネントが含まれています。

これらのコンポーネントをテンプレートで使用するためには、 Vue がそれらを認識できるように登録する必要があります。 コンポーネントの登録には**グローバル**と**ローカル**の 2 種類があります。これまでは、アプリケーションの `component` メソッドを利用してグローバルに登録してきただけです:
これらのコンポーネントをテンプレートで使用するためには、 Vue がそれらを認識できるように登録する必要があります。コンポーネントの登録には**グローバル**と**ローカル**の 2 種類があります。これまでは、アプリケーションの `component` メソッドを利用してグローバルに登録してきただけです:

```js
const app = Vue.createApp({})
Expand All @@ -76,15 +76,15 @@ app.component('my-component-name', {
})
```

グローバルに登録されたコンポーネントはその後作成された `app` インスタンスのテンプレートで使用することができます。さらに、ルートインスタンスのコンポーネントツリーの全てのサブコンポーネント内でも使用することが出来ます
グローバルに登録されたコンポーネントは、アプリケーション内のどのコンポーネントのテンプレートでも使うことができます

とりあえずコンポーネント登録についてはこれで以上ですが、このページを読み終えて十分に理解できたら、後から戻ってきて[コンポーネント登録](component-registration.md)の完全なガイドを読むことをお勧めします。

## プロパティを用いた子コンポーネントへのデータの受け渡し

先ほど、 ブログ投稿用のコンポーネントの作成について触れました。問題は、 表示する特定の投稿のタイトルや内容のようなデータを作成したコンポーネントに渡せなければそのコンポーネントは役に立たないということです。プロパティはここで役立ちます。
先ほど、ブログ投稿用のコンポーネントの作成について触れました。問題は、表示する特定の投稿のタイトルや内容のようなデータを作成したコンポーネントに渡せなければそのコンポーネントは役に立たないということです。プロパティはここで役立ちます。

プロパティはコンポーネントに登録できるカスタム属性です。値がプロパティ属性に渡されると、そのコンポーネントインスタンスのプロパティになります。先ほどのブログ投稿用のコンポーネントにタイトルを渡すためには、`props`オプションを用いてこのコンポーネントが受け取るプロパティのリストの中に含めることができます:
プロパティはコンポーネントに登録できるカスタム属性です。値がプロパティ属性に渡されると、そのコンポーネントインスタンスのプロパティになります。先ほどのブログ投稿用のコンポーネントにタイトルを渡すためには、`props` オプションを用いてこのコンポーネントが受け取るプロパティのリストの中に含めることができます:

```js
const app = Vue.createApp({})
Expand All @@ -97,9 +97,11 @@ app.component('blog-post', {
app.mount('#blog-post-demo')
```

コンポーネントは必要に応じて多くのプロパティを持つことができ、デフォルトでは任意のプロパティに任意の値を渡すことができます。上記のテンプレートでは、`data` と同様に、コンポーネントインスタンスでこの値にアクセスできることが分かります
プロパティ属性に値が渡されると、渡されたそのコンポーネントインスタンスのプロパティになります。そのプロパティの値は、他のコンポーネントのプロパティと同じように、テンプレート内でアクセスができます

プロパティが登録されたら、 次のようにカスタム属性としてデータをプロパティに渡すことができます:
コンポーネントは必要に応じて多くのプロパティを持つことができ、デフォルトでは任意のプロパティに任意の値を渡すことができます。

プロパティが登録されたら、次のようにカスタム属性としてデータをプロパティに渡すことができます:

```html
<div id="blog-post-demo" class="demo">
Expand Down Expand Up @@ -154,7 +156,7 @@ app.mount('#blog-posts-demo')

## 子コンポーネントのイベントを購読する

`<blog-post>` コンポーネントを開発する中で、いくつかの機能で親コンポーネントとの通信が必要になるかもしれません。例えば、残りの部分の大きさはそのままで、ブログ記事の文字の文字を拡大するアクセシビリティ機能を実装することを決めるかもしれません
`<blog-post>` コンポーネントを開発する中で、いくつかの機能で親コンポーネントとの通信が必要になるかもしれません。例えば、ページの他の部分の大きさはそのままで、ブログ記事のテキストを拡大するアクセシビリティ機能を実装することを決めるかもしれません

親コンポーネントでは、`postFontSize` データプロパティを追加することでこの機能をサポートすることができます:

Expand All @@ -171,7 +173,7 @@ const App = {
}
```

すべてのブログ投稿のフォントサイズを制御するためにテンプレート内で使用できます:
これはすべてのブログ投稿のフォントサイズを制御するためにテンプレート内で使用できます:

```html
<div id="blog-posts-events-demo">
Expand Down Expand Up @@ -209,25 +211,25 @@ app.component('blog-post', {
</button>
```

ボタンをクリックすると、全ての投稿のテキストを拡大する必要があることを親に伝える必要があります。親は、ネイティブ DOM イベントでの場合と同様に、 `v-on` や `@` を用いて子コンポーネントのインスタンスでのイベントを購読することができます:
ボタンをクリックすると、全ての投稿のテキストを拡大する必要があることを親に伝える必要があります。この問題を解決するために、コンポーネントインスタンスはカスタムイベントの仕組みを提供しています。親は、ネイティブ DOM イベントでの場合と同様に、 `v-on` や `@` を用いて子コンポーネントのインスタンスでのイベントを購読することができます:

```html
<blog-post ... @enlarge-text="postFontSize += 0.1"></blog-post>
```

そして子コンポーネントはビルトインの [**`$emit`** メソッド](../api/instance-methods.html#emit)にイベントの名前を渡して呼び出すことで、イベントを送出することができます:
そして子コンポーネントはビルトインの [**`$emit`** メソッド](../api/instance-methods.html#emit)にイベントの名前を渡して呼び出すことで、イベントを発行することができます:

```html
<button @click="$emit('enlargeText')">
Enlarge text
</button>
```

親コンポーネントは `v-on:enlarge-text="postFontSize += 0.1"` リスナーによって、このイベントを受け取り `postFontSize` を更新することができます
`@enlarge-text="postFontSize += 0.1"` リスナによって、親コンポーネントはこのイベントを受け取り `postFontSize` の値を更新することができます

<common-codepen-snippet title="Component basics: emitting events" slug="KKpGyrp" tab="html,result" :preview="false" />

コンポーネントの `emits` オプションにより排出されたイベントをリストアップすることができます。
コンポーネントの `emits` オプションにより発行されたイベントを一覧することができます:

```js
app.component('blog-post', {
Expand All @@ -238,9 +240,9 @@ app.component('blog-post', {

これにより、コンポーネントが排出する全てのイベントをチェックし、オプションでそれらを[検証する](component-custom-events.html#validate-emitted-events)ことができます。

### イベントと値を送出する
### イベントと値を発行する

イベントを特定の値と一緒に送出すると便利な場合があります。例えば、テキストをどれだけ大きく表示するかを `<blog-post>` コンポーネントの責務とさせたいかもしれません。そのような場合、 `$emit` の第二引数を使ってこの値を渡すことができます:
イベントを特定の値と一緒に発行すると便利な場合があります。例えば、テキストをどれだけ大きく表示するかを `<blog-post>` コンポーネントの責務とさせたいかもしれません。そのような場合、 `$emit` の第二引数を使ってこの値を渡すことができます:

```html
<button @click="$emit('enlargeText', 0.1)">
Expand Down Expand Up @@ -300,13 +302,14 @@ methods: {
これが実際に機能するためには、テンプレート内の `<input>` は以下でなければなりません:

- `value` 属性を `modelValue` プロパティにバインドする
- `input` では、 `update:modelValue` イベントを新しい値と共に送出する
- `input` では、 `update:modelValue` イベントを新しい値と共に発行する

以下のようになります:

```js
app.component('custom-input', {
props: ['modelValue'],
emits: ['update:modelValue'],
template: `
<input
:value="modelValue"
Expand All @@ -322,15 +325,12 @@ app.component('custom-input', {
<custom-input v-model="searchText"></custom-input>
```

カスタムコンポーネント内で `v-model` を使うもう一つの方法は `computed` プロパティを利用してゲッターとセッターを定義することです。

以下の例では、computed プロパティを用いて `custom-input` コンポーネントをリファクタリングします。

注意して欲しいのは、 `get` メソッドは `modelValue` 属性を返し、バインディングに使用しているプロパティがどれであるかに関わらず、 `set` メソッドはそのプロパティに対応する `$emit` を送出しなければならないということです。
このコンポーネント内で `v-model` を実装するもう一つの方法は `computed` プロパティの機能を使ってゲッターとセッターを定義することです。 `get` メソッドは `modelValue` プロパティを返して、 `set` メソッドは対応するイベントを発行する必要があります。

```js
app.component('custom-input', {
props: ['modelValue'],
emits: ['update:modelValue'],
template: `
<input v-model="value">
`,
Expand Down Expand Up @@ -363,7 +363,7 @@ HTML 要素のように、コンポーネントに要素を渡すことができ

<common-codepen-snippet title="Component basics: slots" slug="jOPeaob" :preview="false" />

幸いにも、この作業は Vue のカスタム `<slot>` 要素により非常に簡単になります:
これは、 Vue のカスタム `<slot>` 要素で達成できます:

```js
app.component('alert-box', {
Expand All @@ -376,7 +376,7 @@ app.component('alert-box', {
})
```

上で見た通り、ただ渡したいところにスロットを追加するだけです。それだけです。終わりです!
上で見た通り、コンテンツを配置したいところにプレースホルダとして `<slot>` を使います。それだけです。終わりです!

とりあえずスロットについてはこれで以上ですが、このページを読み終えて十分に理解できたら、後から戻ってきて[スロット](component-slots.md)の完全なガイドを読むことをお勧めします。

Expand All @@ -386,7 +386,7 @@ app.component('alert-box', {

<common-codepen-snippet title="Component basics: dynamic components" slug="oNXaoKy" :preview="false" />

上記は Vue の `<component>` 属性に特別な属性である `is` を持たせることで実現しています:
上記は Vue の `<component>` 要素に特別な `is` 属性を持たせることで実現しています:

```html
<!-- コンポーネントは currentTabComponent に変更があったときに変更されます -->
Expand All @@ -400,7 +400,7 @@ app.component('alert-box', {

完全なコードを試すには [この例](https://codepen.io/team/Vue/pen/oNXaoKy)、登録された名前ではなくコンポーネントのオプションオブジェクトをバインドしている例は[こちらのバージョン](https://codepen.io/team/Vue/pen/oNXapXM)を参照してください。

この属性は通常の HTML 要素で使用することができますが、それらはコンポーネントとして扱われ、すべての属性は **DOM 属性としてバインドされる**ことを覚えておいてください。 `value` のようないくつかのプロパティが期待通りに動作するためには、 [`.prop` 修飾子](../api/directives.html#v-bind)を用いてバインドする必要があります
また、 `is` 属性を使って通常の HTML 要素を作ることもできます

とりあえず動的なコンポーネントについてはこれで以上ですが、このページを読み終えて十分に理解できたら、後から戻ってきて[動的 & 非同期コンポーネント](./component-dynamic-async.html)の完全なガイドを読むことをお勧めします。

Expand All @@ -416,7 +416,7 @@ app.component('alert-box', {
</table>
```

このカスタムコンポート `<blog-post-row>` は無効なコンテンツとして摘み出され、最終的に描画された内容にエラーが発生します。幸い、これを回避するために `v-is` という特殊なディレクティブを使用することができます:
このカスタムコンポーネント `<blog-post-row>` は無効なコンテンツとして巻き取られ、最終的にレンダリングされた出力でエラーが発生します。回避策として特別な `v-is` ディレクティブを使うことができます:

```html
<table>
Expand All @@ -425,7 +425,7 @@ app.component('alert-box', {
```

:::warning
`v-is` の値は JavaScript の文字列リテラルである必要があります:
`v-is` の値は JavaScript の式として扱われるので、コンポーネント名を引用符で囲む必要があります:

```html
<!-- 間違い、何も出力されません-->
Expand Down