Vue.js 3.0 Tutorial

Vue.js 3.0 Component Advanced

Vue.js 3.0 Transitions & Animations

Vue.js 3.0 Reusable & Combinable

Vue.js 3.0 Advanced

Vue.js 3.0 Tools

Vue.js 3.0 Scale

Vue.js 3.0 Accessibility

Vue.js 3.0 Migrating from Vue2

Vue.js 3.0 Contribute Documentation

Vue.js 3.0 API References

Vue.js 3.0 Style Guide

Vue 3.0 custom directive

Custom directives allow you to attach custom behavior to elements in your Vue templates. They can be useful for direct DOM manipulation, which Vue discourages in most cases, but can be necessary for integrating with non-Vue libraries or for adding custom functionality that doesn't fit into the component-based model.

Let's create a simple custom directive in Vue 3:

import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)

app.directive('focus', {
  mounted(el) {
    el.focus()
  }
})

app.mount('#app')

In this example, we're creating a v-focus directive that focuses the element when it's mounted to the DOM.

We can use it in our templates like this:

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

Now, when this component is mounted, the input field will be automatically focused.

Here's a breakdown of how to create a custom directive in Vue 3:

  • Use the directive method on the application instance to define a global directive.
  • The first argument to the directive method is the name of the directive, which you can then use in your templates with a v- prefix.
  • The second argument is an object that defines the directive's lifecycle hooks.

The lifecycle hooks of a directive correspond to the lifecycle of the element it's attached to, not to the lifecycle of the component. Here's a list of the directive lifecycle hooks:

  • beforeMount: called right before the directive's element is mounted to the DOM.
  • mounted: called when the directive's element has been mounted to the DOM. The element is available as the first argument to the hook function.
  • beforeUpdate: called before the component's VNode is updated.
  • updated: called after the component's VNode and the VNodes of its children have updated.
  • beforeUnmount: called right before the directive's element is unmounted from the DOM.
  • unmounted: called after the directive's element has been unmounted from the DOM.

You can use these hooks to add and clean up event listeners, manipulate the element's styles or properties, etc. Be aware that these hooks should only be used for direct manipulation of the DOM; any data changes should be done through the component's data and methods.

  1. Vue 3.0 Directive Hooks: Custom directives have lifecycle hooks, including beforeMount, mounted, beforeUpdate, updated, and beforeUnmount.

    app.directive('custom-directive', {
      beforeMount(el, binding, vnode, prevVNode) {
        // ...
      },
      mounted(el, binding, vnode, prevVNode) {
        // ...
      },
      // ...
    });
    
  2. Vue 3.0 Custom Directive Options: Directives can have various options, such as bind, update, and unbind.

    app.directive('custom-directive', {
      bind(el, binding) {
        // ...
      },
      update(el, binding) {
        // ...
      },
      // ...
    });
    
  3. Vue 3.0 Directive Modifiers: Use modifiers to customize the behavior of directives.

    <p v-custom-directive.capitalize>Text</p>
    
    app.directive('custom-directive', {
      // ...
      bind(el, binding) {
        if (binding.modifiers.capitalize) {
          // Capitalize the text
          el.textContent = el.textContent.toUpperCase();
        }
      },
      // ...
    });
    
  4. Vue 3.0 Custom Directive Example: Create a simple custom directive that changes the background color.

    app.directive('bg-color', {
      beforeMount(el, binding) {
        el.style.backgroundColor = binding.value;
      },
      updated(el, binding) {
        el.style.backgroundColor = binding.value;
      },
    });
    
    <div v-bg-color="'red'">Red Background</div>
    
  5. Vue 3.0 Directive Binding and Expressions: Bind values and expressions to custom directives.

    <div v-custom-directive="{ arg: 'argValue', value: 'directiveValue' }"></div>
    
    app.directive('custom-directive', {
      bind(el, binding) {
        console.log(binding.arg); // 'argValue'
        console.log(binding.value); // 'directiveValue'
      },
    });
    
  6. Vue 3.0 Directive Lifecycle Hooks: Lifecycle hooks, like bind, inserted, update, and componentUpdated, enable you to respond to different stages.

    app.directive('custom-directive', {
      bind(el, binding) {
        // ...
      },
      inserted(el, binding) {
        // ...
      },
      update(el, binding) {
        // ...
      },
      componentUpdated(el, binding) {
        // ...
      },
      unbind(el, binding) {
        // ...
      },
    });
    
  7. Registering and Using Custom Directives in Vue 3.0: Register custom directives globally or locally in components.

    // Globally
    app.directive('custom-directive', {
      // ...
    });
    
    // Locally
    const MyComponent = {
      directives: {
        'local-directive': {
          // ...
        },
      },
      // ...
    };
    
  8. Vue 3.0 Global Custom Directives: Register a directive globally for use throughout the entire app.

    app.directive('global-directive', {
      // ...
    });
    
    <div v-global-directive></div>
    
  9. Vue 3.0 Directive Context and Arguments: Access the directive's context and arguments in hooks.

    app.directive('custom-directive', {
      bind(el, binding) {
        console.log(binding.arg); // Argument
        console.log(binding.value); // Value
        console.log(binding.instance); // Vue instance
      },
    });
    
  10. Vue 3.0 Custom Directives for DOM Manipulation: Create directives for direct DOM manipulation.

    app.directive('focus', {
      mounted(el) {
        el.focus();
      },
    });
    
    <input v-focus>
    
  11. Vue 3.0 v-model with Custom Directives: Extend v-model behavior with a custom directive.

    app.directive('model', {
      beforeMount(el, binding) {
        el.value = binding.value;
        el.addEventListener('input', () => {
          binding.value = el.value;
        });
      },
    });
    
    <input v-model="myValue" v-model:model="customModel">
    
  12. Vue 3.0 Custom Directives and Reactivity: Leverage reactivity with custom directives.

    app.directive('custom-directive', {
      beforeMount(el, binding) {
        el.textContent = binding.value;
        watchEffect(() => {
          el.textContent = binding.value;
        });
      },
    });
    
    <p v-custom-directive="reactiveValue"></p>