Skip to content

docs (#2194): fix issue with autofocus on custom directives page #2994

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
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 {#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 {#introduction}

In addition to the default set of directives shipped in core (like `v-model` or `v-show`), Vue also allows you to register your own custom directives.
Expand All @@ -20,14 +31,16 @@ A custom directive is defined as an object containing lifecycle hooks similar to

```vue
<script setup>
// enables v-focus in templates
const vFocus = {
mounted: (el) => el.focus()
// enables v-highlight in templates
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,44 +49,42 @@ 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: {
// enables v-focus in template
focus
// enables v-highlight in template
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>

Assuming you haven't clicked elsewhere on the page, the input above should be auto-focused. This directive is more useful than the `autofocus` attribute because it works not just on page load - it also works when the element is dynamically inserted by Vue.

<div class="composition-api">

In `<script setup>`, any camelCase variable that starts with the `v` prefix can be used as a custom directive. In the example above, `vFocus` can be used in the template as `v-focus`.
In `<script setup>`, any camelCase variable that starts with the `v` prefix can be used as a custom directive. In the example above, `vHighlight` can be used in the template as `v-highlight`.

If not using `<script setup>`, custom directives can be registered using the `directives` option:
If you are not using `<script setup>`, custom directives can be registered using the `directives` option:

```js
export default {
setup() {
/*...*/
},
directives: {
// enables v-focus in template
focus: {
// enables v-highlight in template
highlight: {
/* ... */
}
}
Expand All @@ -94,14 +105,58 @@ It is also common to globally register custom directives at the app level:
const app = createApp({})

// make v-focus usable in all components
app.directive('focus', {
app.directive('highlight', {
/* ... */
})
```

:::tip
Custom directives should only be used when the desired functionality can only be achieved via direct DOM manipulation. Prefer declarative templating using built-in directives such as `v-bind` when possible because they are more efficient and server-rendering friendly.
:::
## When to use custom directives {#when-to-use}

Custom directives should only be used when the desired functionality can only be achieved via direct DOM manipulation.

A common example of this is a `v-focus` custom directive that brings an element into focus.

<div class="composition-api">

```vue
<script setup>
// enables v-focus in templates
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: {
// enables v-focus in template
focus
}
}
```

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

</div>

This directive is more useful than the `autofocus` attribute because it works not just on page load - it also works when the element is dynamically inserted by Vue!

Declarative templating with built-in directives such as `v-bind` is recommended when possible because they are more efficient and server-rendering friendly.

## Directive Hooks {#directive-hooks}

Expand Down Expand Up @@ -214,7 +269,6 @@ app.directive('demo', (el, binding) => {
Using custom directives on components is not recommended. Unexpected behaviour may occur when a component has multiple root nodes.
:::


When used on components, custom directives will always apply to a component's root node, similar to [Fallthrough Attributes](/guide/components/attrs).

```vue-html
Expand Down