Skip to content

Guide > Reusability & Composition > Custom Directives の翻訳を追従 #291

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 5 commits into from
Apr 28, 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
52 changes: 18 additions & 34 deletions src/guide/custom-directive.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Vue.js 本体で提供されているデフォルトのディレクティブ (`v

<common-codepen-snippet title="Custom directives: basic example" slug="JjdxaJW" :preview="false" />

ページを読み込むと、この要素にフォーカスが当たります (注意:`autofucus` はモバイルの Safari で動きません)。実際、このページに訪れてから他に何もクリックしなければ、上記の input 要素にフォーカスが当たります。また、`Rerun` ボタンをクリックしても、input 要素はフォーカスされます。
ページを読み込むと、この要素にフォーカスが当たります (注意:`autofocus` はモバイルの Safari で動きません)。実際、このページに訪れてから他に何もクリックしなければ、上記の input 要素にフォーカスが当たります。また、`Rerun` ボタンをクリックしても、input 要素はフォーカスされます。

ここからこれを実現するディレクティブを実装しましょう:

Expand Down Expand Up @@ -45,7 +45,9 @@ directives: {

ディレクティブの定義オブジェクトは、いくつかのフック関数を提供しています (全てオプション):

- `beforeMount`: ディレクティブが初めて要素に束縛された時、そして親コンポーネントがマウントされる前に呼ばれます。ここは1度だけ実行するセットアップ処理を行える場所です。
- `created`: 束縛された要素の属性や、イベントリスナが適用される前に呼ばれます。これは通常の `v-on` イベントリスナの前に呼ばれなければならないイベントリスナをつける必要がある場合に便利です。

- `beforeMount`: ディレクティブが最初に要素に束縛されたとき、親コンポーネントがマウントされる前に呼ばれます。

- `mounted`: 束縛された要素の親コンポーネントがマウントされた時に呼ばれます。

Expand Down Expand Up @@ -130,7 +132,7 @@ app.mount('#dynamic-arguments-example')
<div id="dynamicexample">
<h2>Scroll down the page</h2>
<input type="range" min="0" max="500" v-model="pinPadding">
<p v-pin:[direction]="pinPadding">Stick me 200px from the {{ direction }} of the page</p>
<p v-pin:[direction]="pinPadding">Stick me {{ pinPadding + 'px' }} from the {{ direction }} of the page</p>
</div>
```

Expand Down Expand Up @@ -167,7 +169,7 @@ app.directive('pin', {

## 関数による省略記法

前回の例では、`mounted` と `updated` に同じ振る舞いを欲しかったでしょう。しかし、その他のフック関数を気にしてはいけません。ディレクティブにコールバックを渡すことで実現できます:
Copy link
Member Author

Choose a reason for hiding this comment

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

この訳が不自然だったので、再翻訳しました。

前の例では、`mounted` と `updated` に同じ振る舞いをさせたいが、その他のフックは気にしない、という場合があります。そのような場合は、ディレクティブにコールバックを渡すことで実現できます:

```js
app.directive('pin', (el, binding) => {
Expand All @@ -192,42 +194,24 @@ app.directive('demo', (el, binding) => {
})
```

## コンポーネントにおける使用法

3.0 ではフラグメントがサポートされているため、コンポーネントは潜在的に1つ以上のルートノードを持つことができます。これは複数のルートノードを持つ1つのコンポーネントにカスタムディレクティブが使用された時に、問題を引き起こします。
## コンポーネントでの使い方

3.0 のコンポーネント上でどのようにカスタムディレクティブが動作するかを詳細に説明するために、3.0 においてカスタムディレクティブがどのようにコンパイルされるのかをまずは理解する必要があります。以下のようなディレクティブは:
コンポーネントに使われた場合、カスタムディレクティブは [プロパティでない属性](component-attrs.html) と同じように、常にコンポーネントのルートノードに適用されます

```vue-html
<div v-demo="test"></div>
```

おおよそ以下のようにコンパイルされます:

```js
const vDemo = resolveDirective('demo')

return withDirectives(h('div'), [[vDemo, test]])
<my-component v-demo="test"></my-component>
```

ここで `vDemo` はユーザによって記述されたディレクティブオブジェクトで、それは `mounted` や `updated` のフック関数を含みます。

`withDirectives` は複製した VNode を返します。複製された VNode は VNode のライフサイクルフック (詳細は[Render 関数](render-function.html)を参照) としてラップ、注入されたユーザのフック関数を持ちます:

```js
{
onVnodeMounted(vnode) {
// vDemo.mounted(...) を呼びます
}
}
app.component('my-component', {
template: `
<div> // v-demo ディレクティブはここで適用される
<span>My component content</span>
</div>
`
})
```

**結果として、VNode のデータの一部としてカスタムディレクティブは全て含まれます。カスタムディレクティブがコンポーネントで利用される場合、これらの `onVnodeXXX` フック関数は無関係な props としてコンポーネントに渡され、最終的に `this.$attrs` になります。**

これは以下のようなテンプレートのように、要素のライフサイクルに直接フックできることを意味しています。これはカスタムディレクティブが複雑すぎる場合に便利です:

```vue-html
<div @vnodeMounted="myHook" />
```
属性とは異なり、ディレクティブは `v-bind="$attrs"` で別の要素に渡すことはできません。

これは [属性のフォールスロー](component-attrs.html) と一貫性があります。つまり、コンポーネントにおけるカスタムディレクティブのルールは、その他の異質な属性と同じです: それをどこにまた適用するかどうかを決めるのは、子コンポーネント次第です。子コンポーネントが内部の要素に `v-bind="$attrs"` を利用している場合、あらゆるカスタムディレクティブもその要素に適用されます
[Fragments](/guide/migration/fragments.html#overview) のサポートによって、コンポーネントは複数のルートノードを持つことができます。マルチルートコンポーネントに適用された場合、ディレクティブは無視され、警告が投げられます