Changeable themes with Vue

Viewed 2310

I am working on an application using Vue.js 2.0. and Vuex for state management. I need to implement the possibility of so-called "branding", i.e. the user needs to have the ability to select a theme for their account, a specific color which will then be applied to the application's style.

The first option I went for and managed to implement as a proof of concept was to use Vuex to store the desired style in the application store as an object with Vuex which I then used for binding to the style of the elements it needs to be applied to. The color picker for choosing the color triggers a mutation on the state to change the color. This works completely fine and isn't even too hard to use as it allows for just using an expression like :style ="$store.state.brand" on the html elements it needs to be applied to. It updates on all components as I change the color. This option has its advantages as it is pretty straight forward and also allows the user to select whichever color he/she wants from a color picker. However, it has its limitations in terms of design, as complicated styles cannot be implemented in this way (e.g.color change on hover, active classes for tabs or pages etc.)

So the second option I would like to try and suggest to our client is to have a set of predefined themes from which the user can choose. Those themes would be defined in css files (using sass/less or something similar). What I need to implement now is the following:

When the user chooses a theme, let's say from a dropdown, I want to load the style for the application from the appropriate css file and reload the application to reflect those changes. What is the most efficient and best practice way to do this in Vue?

1 Answers

So in case anyone else needs this, we ended up using styled components. For more details, checkout https://www.npmjs.com/package/vue-styled-components. We created styled components for elements that need to receive the specified theme's color (button, radio button, header, menu items etc.) and passed them the required color in as a prop. The value of the prop comes from the Vuex store so it is consistent across the whole application. The benefit of this approach is that the color choices are limitless for the client (compared to the predefined themes we were considering). Furthermore another benefit is that now the client can let's say change the color in the vuex store through a color picker and see the theme changing live. Finally, this approach also enables you to use all features of css like creating more complex styles with css selectors for example. This was not possible with regular vue style bindings. Feel free to contact me if you need more details on this.

Related