Skip to content

docs: fix issue with autofocus on custom directives page #2330

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
Sep 29, 2024
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
100 changes: 77 additions & 23 deletions src/guide/reusability/custom-directives.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
# カスタムディレクティブ {#custom-directives}

<script setup>
const vFocus = {
const vHighlight = {
mounted: el => {
el.focus()
el.classList.add('is-highlight')
}
}
</script>

<style>
.vt-doc p.is-highlight {
margin-bottom: 0;
}

.is-highlight {
background-color: yellow;
color: black;
}
</style>

## はじめに {#introduction}

コアに設定されているデフォルトのディレクティブのセット(`v-model` や `v-show` など)に加え、Vue では独自のカスタムディレクティブを登録することができます。
Expand All @@ -20,14 +31,16 @@ Vue におけるコードの再利用として 2 つの方法を紹介してき

```vue
<script setup>
// テンプレート内で v-focus が有効になります
const vFocus = {
mounted: (el) => el.focus()
// テンプレート内で v-highlight が有効になります
const vHighlight = {
mounted: (el) => {
el.classList.add('is-highlight')
}
}
</script>

<template>
<input v-focus />
<p v-highlight>This sentence is important!</p>
</template>
```

Expand All @@ -36,33 +49,31 @@ const vFocus = {
<div class="options-api">

```js
const focus = {
mounted: (el) => el.focus()
const highlight = {
mounted: (el) => el.classList.add('is-highlight')
}

export default {
directives: {
// テンプレート内で v-focus が有効になります
focus
// テンプレート内で v-highlight が有効になります
highlight
}
}
```

```vue-html
<input v-focus />
<p v-highlight>This sentence is important!</p>
```

</div>

<div class="demo">
<input v-focus placeholder="This should be focused" />
<p v-highlight>This sentence is important!</p>
</div>

ページの他の場所をクリックしていないと仮定すると、上の入力欄は自動的にフォーカスされるはずです。このディレクティブはページロード時だけでなく、Vue によって要素が動的に挿入されたときにも機能するため、`autofocus` 属性よりも便利です。

<div class="composition-api">

`<script setup>` では、接頭辞が `v` で始まるキャメルケースの変数をカスタムディレクティブとして使用することができます。上の例では、`vFocus` はテンプレート内で `v-focus` として使用できます。
`<script setup>` では、接頭辞が `v` で始まるキャメルケースの変数をカスタムディレクティブとして使用することができます。上の例では、`vHighlight` はテンプレート内で `v-highlight` として使用できます。

`<script setup>` を使用しない場合、カスタムディレクティブは `directives` オプションを使用して登録することができます:

Expand All @@ -72,8 +83,8 @@ export default {
/*...*/
},
directives: {
// テンプレート内で v-focus が有効になります
focus: {
// テンプレート内で v-highlight が有効になります
highlight: {
/* ... */
}
}
Expand All @@ -93,15 +104,59 @@ export default {
```js
const app = createApp({})

// 全てのコンポーネントで v-focus が使用可能
app.directive('focus', {
// 全てのコンポーネントで v-highlight が使用可能
app.directive('highlight', {
/* ... */
})
```

:::tip
カスタムディレクティブは DOM を直接操作することでしか必要な機能を実現できない場合にのみ使用してください。`v-bind` のような組み込みディレクティブを使用した宣言的なテンプレートは、効率的かつサーバーレンダリングフレンドリーです。可能なかぎり組み込みディレクティブを使用することをおすすめします。
:::
## カスタムディレクティブを使用するタイミング {#when-to-use}

カスタムディレクティブは DOM を直接操作することでしか必要な機能を実現できない場合にのみ使用してください。

一般的な例として、要素にフォーカスを当てる `v-focus` カスタムディレクティブがあります。

<div class="composition-api">

```vue
<script setup>
// テンプレート内で v-focus が有効になります
const vFocus = {
mounted: (el) => el.focus()
}
</script>

<template>
<input v-focus />
</template>
```

</div>

<div class="options-api">

```js
const focus = {
mounted: (el) => el.focus()
}

export default {
directives: {
// テンプレート内で v-focus が有効になります
focus
}
}
```

```vue-html
<input v-focus />
```

</div>

このディレクティブは `autofocus` 属性よりも便利です。ページ読み込み時だけでなく、Vue によって要素が動的に挿入されたときにも機能するからです!

可能な限り `v-bind` のような組み込みディレクティブを使用した宣言的なテンプレートを推奨します。これらはより効率的で、サーバーレンダリングにも適しているためです。

## ディレクティブフック {#directive-hooks}

Expand Down Expand Up @@ -214,7 +269,6 @@ app.directive('demo', (el, binding) => {
コンポーネントにカスタムディレクティブを使用することは推奨しません。コンポーネントに複数のルートノードがある場合、予期しない動作が発生する可能性があります。
:::


コンポーネントで使用すると、[フォールスルー属性](/guide/components/attrs)と同様にカスタムディレクティブは常にコンポーネントのルートノードに適用されます。

```vue-html
Expand Down