·
2 min read

Vue Tip: Creating a Custom Directive

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.

Info

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.

Warning

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 X 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.