Aslam Doctor

Add dynamic style tag inside Vue template tag

So here is a common situation I was into recently. I am building a portal using NuxtJS, NodeJS & MongoDB stack and the requirement was to store design preferences for a specific user. So a user can log in and set up their profile text color, background color, button styles, etc. And the first question popped in my mind was, how do I add all these styles dynamically in NuxtJS (or you can say VueJS)? There is a couple of solution, some of which can work and some don’t.

1. By binding style attribute

This is a very common method as you can dynamically bind any attributes to HTML tags in Vue JS. So doing something like the below would work nicely

<h1 :style="{ color: activeColor, fontSize: fontSize + 'px' }">Hello World</h1>

Nicely explained on official documentation. But there is one problem here, what if you want to apply styles like :hover, :nth-child, :active, :focus, etc?  This solution will not work.

2. By adding <style> tag inside <template> tag

This method is actually wrong but for some reason it worked for me on my local machine and then after deploying, it didn’t 😆

<template>
... other code ...
<style>
h1{ color: {{activeColor}}, fontSize: {{fontSize}}px }
</style>
</template>

Later I found that some people tried this method and got the below warning:

Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as , as they will not be parsed.

3. Using Dynamic component

VueJS has a nice feature to load components dynamically. Which means you can simply write <component :is=”COMPONENT_NAME”> and the component with that name gets loaded. And we can make use of it to load <style> tag inside <template> tag. Something like this:

<template>
<h1>Hello World</h1>>

<component :is="'style'">
h1{ color: {{activeColor}}, fontSize: {{fontSize}}px }
</component>
</template>

Notice the :is=”‘style'”, here you can not write is=”style” directly as “is” always has to be bound to some component name. In our case style is an inbuilt HTML component, so we are simply passing it as a string and not as a component.

This method worked for me without any errors. But there is no official statement about this if we should use it this way or not. I found this solution from Vuejs forum . Make note the solution given on forum doesn’t have the is bound which causes error. So :is should always be bound.