VueJS - v-bind:style + hover
Improved solution: use CSS custom properties and variables
If you only intend to work with modern/evergreen browsers, then using CSS custom properties and variables is the way to go! You can actually pass CSS custom properties into the :style
binding, e.g.
computed: {
styleObject: function() {
return {
'--color': this.button.color,
'--color-hover': this.button.colorHover
}
}
}
And in your template:
<custom-button :style="styleObject" />
For the CSS, it's just a matter of:
button {
color: var(--color);
}
button:hover {
color: var(--color-hover);
}
The advantage of this method is that you can scope CSS custom properties, so these variables will only apply to your specific button component when you define the CSS properties at the element level (instead of in :root
).
The only drawback is that you have to iteratively declare all the variables in both hover and unhovered states, which can be a little bit cumbersome. However, I see this is a very minor disadvantage, compared to the benefits that you reap from using CSS variables.
See proof-of-concept below:
var customButton = Vue.component('custom-button', {
template: '#custom-button',
data() {
return {
button: {
colorBackd: '#1e2021',
colorBackdHover: '#000000',
text: 'Results',
color: '#d3e0ff',
colorHover: "#ffffff",
borderColor: '#d3e0ff',
borderColorHover: "#ffffff"
}
};
},
computed: {
styleObject() {
return {
'--button-color': this.button.color,
'--button-background-color': this.button.colorBackd,
'--button-border-color': this.button.borderColor,
'--button-color--hover': this.button.colorHover,
'--button-background-color--hover': this.button.colorBackdHover,
'--button-border-color': this.button.borderColorHover
};
},
},
});
new Vue({
el: '#app'
});
button {
color: var(--button-color);
background-color: var(--button-background-color);
border-color: var(--button-border-color);
}
button:hover {
color: var(--button-color--hover);
background-color: var(--button-background-color--hover);
border-color: var(--button-border-color--hover);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script>
<div id="app">
<custom-button></custom-button>
</div>
<script type="text/template" id="custom-button">
<button type="button" :style="styleObject" class="btn btn-outline-info large-button">
{{ button.text }}
</button>
</script>
Original sotluion: use JS-based mouse events
You can store the hovered state of the element in its data
, say hoverState
. It is set to false
by default, and is toggled to true
when @mouseenter
is fired, and back to false
when @mouseleave
is triggered:
Then, you can simply bind a computed property to the style
attribute, for example, styleObject
. In this styleObject
, you can return the correct CSS styles depending on the hoverState
found in the component's data:
var customButton = Vue.component('custom-button', {
template: '#custom-button',
data() {
return {
button: {
colorBackd: '#1e2021',
colorBackdHover: '#000000',
text: 'Results',
color: '#d3e0ff',
colorHover: "#ffffff",
borderColor: '#d3e0ff',
borderColorHover: "#ffffff"
},
hoverState: false
};
},
computed: {
styleObject() {
var modifier = '';
if (this.hoverState)
modifier = 'Hover';
return {
color: this.button['color' + modifier],
backgroundColor: this.button['colorBackd' + modifier],
borderColor: this.button['borderColor' + modifier]
};
},
},
methods: {
updateHoverState(isHover) {
this.hoverState = isHover;
}
}
});
new Vue({
el: '#app'
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script>
<div id="app">
<custom-button></custom-button>
</div>
<script type="text/template" id="custom-button">
<button type="button" :style="styleObject" @mouseenter="updateHoverState(true)" @mouseleave="updateHoverState(false)" class="btn btn-outline-info large-button">
{{ button.text }}
</button>
</script>
Other way (using css variables).
You need create HTML with style
<style>
div[vueid=${_uid}] { --btn-hover: ${`Here your hover brush`} }
</style>
and inject it into your component.
<template>
<div vueid="_uid">
<button></button>
<div v-html="styleCode"></div>
</div>
</template>
Then simply use this variable in static css
file to setup button style.
button:hover { background: var(--btn-hover); }
Note: you can describe default variable value in :root
selector.
You can assign your Vuejs Component an id and apply the required hover style in a stylesheet.
<button id="styledButton" type="button"
:style="{
color:button.color,
backgroundColor:button.colorBackd,
borderColor:button.borderColor,
}"
class="btn btn-outline-info large-button">
{{ button.text }}
</button>
then in tag,
<style>
styledButton:hover {
color: #FFFFFF
};
</style>
If you want the hover style to contain any dynamic data. make a tag that calls a computed property.
<style>{{computedStyle}}</style>