We’re all a fan of using directives in Vue.js. So much, that it’s impossible to think of creating an app without using any directive. v-model, v-for, v-if etc are probably some of the most popular directives we use all the time.
However, Vue.js not only allows you to use in-built directives, but you can even create your own directives and use them wherever needed. This could actually save you tons of code. Especially if you like doing things the JS way more than the CSS way.
Here I’m starting with a quick example on how you can create a v-fontSize directive to control you font size on any element without using any CSS class or dynamically binding a class.
Single Vue directive
Here’s my main.js file of the app:
import Vue from "vue";
import App from "./App.vue";
Vue.config.productionTip = false;
Vue.directive("fontSize", {
bind(el, binding, vnode) {
el.style.fontSize = `${binding.value}px`;
}
});
new Vue({
render: (h) => h(App)
}).$mount("#app");
Code language: JavaScript (javascript)
As you can see in the above code, I’ve registered a directive with the Vue.directive() method. I’ve named it fontSize and have bind the argument value directly to the element’s fontSize.
Now, I can access the directive easily from a Vue template as follows:
<template>
<div id="app">
<div v-fontSize="50">Hello there!</div>
<div class="np-credits">wwww.nightprogrammer.com</div>
</div>
</template>
<script>
export default {
name: "App",
};
</script>
<style>
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
padding: 24px;
}
.np-credits {
font-size: 12px;
margin-top: 12px;
color: #4b4b4b;
}
</style>
Code language: HTML, XML (xml)
The above code will output Hello there! written in the font-size of 50px!
Multiple Vue directives
You can even add multiple Vue directives. Here in this example, I’m creating an array of directives containing the directive name and the directive binding functionality. I’d then register each of the directive with the Vue.directive() global method.
Here’s how my main.js file would now look like:
import Vue from "vue";
import App from "./App.vue";
Vue.config.productionTip = false;
const customDirectives = [
{
directiveName: "fontSize",
directiveBind: {
bind(el, binding, vnode) {
el.style.fontSize = `${binding.value}px`;
}
}
},
{
directiveName: "fontStyle",
directiveBind: {
bind(el, binding, vnode) {
const validFontStyles = [
"normal",
"italic",
"oblique",
"initial",
"inherit"
];
if (validFontStyles.includes(binding.arg)) {
el.style.fontStyle = `${binding.arg}`;
}
}
}
}
];
customDirectives.forEach((d) => {
Vue.directive(d.directiveName, d.directiveBind);
});
new Vue({
render: (h) => h(App)
}).$mount("#app");
Code language: JavaScript (javascript)
I’ve created a list of directives containing fontSize and fontStyle (on line 6). I’ve then registered these directives through an iteration on line 34. It’s worth noting that the bind method (on line 18) takes in binding as the second argument. You can access the argument itself from binding by using binding.arg. Or you can access the argument value using binding.value. That is, for instance, for a directive of v-font:color=”red”
- binding.arg would be “color”
- binding.value would be “red”
Now, let’s use the above directives (fontSize and fontStyle) in the template:
<template>
<div id="app">
<div v-fontSize="50">Hello there!</div>
<div v-fontStyle:italic>This is Gautam</div>
<div class="np-credits">wwww.nightprogrammer.com</div>
</div>
</template>
<script>
export default {
name: "App",
};
</script>
<style>
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
padding: 24px;
}
.np-credits {
font-size: 12px;
margin-top: 12px;
color: #4b4b4b;
}
</style>
Code language: HTML, XML (xml)
The output of the above code would look like:
You can find a working demo from my repo links below: