Vue3 Style Binding
Vue.js Class
Class and style are attributes of HTML elements used to set the element's style. We can use v-bind
to set these attributes.
When handling class and style with v-bind
, the expressions can be strings, objects, or arrays.
v-bind:class
can be abbreviated as :class
.
Class Attribute Binding
We can set an object for v-bind:class
to dynamically switch class:
Example 1
In this example, setting isActive
to true displays a green div block, and setting it to false hides it:
<div :class="{ 'active': isActive }"></div>
The rendered result for the div class in the above example is:
<div class="active"></div>
We can also pass more attributes in the object to dynamically switch multiple classes.
Additionally, the :class
directive can coexist with the regular class attribute.
Example 2
The text-danger
class background color overrides the active
class background color:
<div class="static" :class="{ 'active' : isActive, 'text-danger' : hasError }">
</div>
The rendered result for the div class in the above example is:
<div class="static text-danger"></div>
When isActive
or hasError
changes, the class attribute value will be updated accordingly. For example, if isActive
is true, the class list will become "static active text-danger".
We can also bind an object directly from the data:
Example 3
The text-danger
class background color overrides the active
class background color:
<div id="app">
<div class="static" :class="classObject"></div>
</div>
Example 3 renders the same result as Example 2.
Furthermore, we can bind a computed property that returns an object. This is a common and powerful pattern:
Example 4
data() {
return {
isActive: true,
error: null
}
},
computed: {
classObject() {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
Array Syntax
We can pass an array to v-bind:class
, as shown in the following example:
Example 5
<div class="static" :class="[activeClass, errorClass]"></div>
The rendered result for the div class in the above example is:
<div class="static active text-danger"></div>
We can also use a ternary expression to toggle classes in the list:
Example 6
errorClass
is always present, and activeClass
is added when isActive
is true:
<div id="app">
<div class="static" :class="[isActive ? activeClass : '', errorClass]"></div>
</div>
The rendered result for the div class in the above example is:
<div class="static text-danger"></div>
Vue.js Style (Inline Style)
We can set styles directly with v-bind:style
, which can be abbreviated as :style
:
Example 7
<div id="app">
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }">tutorialpro.org</div>
</div>
The rendered result for the div style in the above example is:
<div style="color: red; font-size: 30px;">tutorialpro.org</div>
We can also bind to a style object to keep the template clear:
Example 8
<div id="app">
<div :style="styleObject">tutorialpro.org</div>
</div>
v-bind:style
can use an array to apply multiple style objects to an element:
Example 9
<div id="app">
<div :style="[baseStyles, overridingStyles]">tutorialpro.org</div>
</div>
Note: When
v-bind:style
uses CSS properties that require vendor prefixes, such astransform
, Vue.js will automatically detect and add the appropriate prefixes.
Multiple Values
You can provide an array of multiple values for a style property, often used for providing prefixed values, for example:
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
This will only render the last value in the array that the browser supports. In this case, if the browser supports unprefixed flexbox, it will render display: flex
.
Using Class Attributes on Components
When you use the class attribute on a custom component with a single root element, these classes will be added to that element. Existing classes on this element will not be overwritten.
Example 10
<div id="app">
<tutorialpro class="classC classD"></tutorialpro>
</div>
<script>
// Create a Vue application
const app = Vue.createApp({})
// Define a new global component named tutorialpro
app.component('tutorialpro', {
template: '<h1 class="classA classB">I like tutorialpro!</h1>'
})
app.mount('#app')
</script>
The rendered result for the div class in the above example is:
<h1 class="classA classB classC classD">I like tutorialpro!</h1>
Data-bound classes also apply:
<my-component :class="{ active: isActive }"></my-component>
When isActive
is true, the HTML will be rendered as:
<p class="active">Hi</p>
If your component has multiple root elements, you need to define which parts will receive this class. You can use the $attrs
component property to do this:
Example 11
<div id="app">
<tutorialpro class="classA"></tutorialpro>
</div>
<script>
const app = Vue.createApp({})
app.component('tutorialpro', {
template: `
<p :class="$attrs.class">I like tutorialpro!</p>
<span>This is a child component</span>
`
})
app.mount('#app')
</script>
Note: In the template, ``is a backtick, not a single quote
'`.
The rendered result for the div class in the above example is:
<div id="app" data-v-app=""><p class="classA">I like tutorialpro!</p><span>This is a child component</span></div>