·
2 min read

Vue Tip: Creating a Custom Directive

MH

Michael Hoffmann

@mokkapps

Vue Tip: Creating a Custom Directive Image

In addition to the default set of directives like v-model or v-show, you can also register your own custom directives. For this article, let's look at how you can create a v-theme directive that applies a specific style to an element of our template.

Custom directives should be used for reusing logic that involves low-level DOM access on plain elements.

You can define the custom directive inside any Vue component:

<template>
  <span v-theme>Test</span>
</template>

<script setup>
// enables v-theme in our template
const vTheme = {
  mounted: (el) => {
    el.style.color = 'red'
  },
}
</script>

Open playground

We defined the custom directive as an object that contains the lifecycle hooks as a Vue component. The element the directive is bound to is available as the first argument of the lifecycle hooks.

In <script setup>, any camelCase variable that starts with the v prefix can be used as a custom directive.

Custom directives should only be used when the desired functionality can only be achieved via direct DOM manipulation. When possible, prefer declarative templating using built-in directives such as v-bind because they are more efficient and server-rendering friendly.

Now let's extend our directive by adding an argument that defines which theme should be applied:

<template>
  <span v-theme:[theme]>Selected theme: {{ theme }}</span>
  <button @click="switchTheme">Switch theme</button>
</template>

<script setup>
import { ref } from 'vue'

const theme = ref('primary')

const switchTheme = () => {
  if (theme.value === 'primary') {
    theme.value = 'secondary'
  } else if (theme.value === 'secondary') {
    theme.value = 'primary'
  }
}

const setThemeColor = (el, binding) => {
  if (binding.arg === 'primary') {
    el.style.color = 'orange'
  } else if (binding.arg === 'secondary') {
    el.style.color = 'green'
  } else {
    el.style.color = 'black'
  }
}

// enables v-theme in our template
const vTheme = {
  mounted(el, binding) {
    setThemeColor(el, binding)
  },
  updated(el, binding) {
    setThemeColor(el, binding)
  },
}
</script>

Open playground

At this point, you have created a custom directive that you can use in your Vue.js application.

Check the official documentation for more information.

If you liked this Vue tip, follow me on BlueSky to get notified about new tips, blog posts, and more. Alternatively (or additionally), you can subscribe to my weekly Vue & Nuxt newsletter :

I will never share any of your personal data. You can unsubscribe at any time.