Seeking assistance in understanding how to control the ordering of a component's root element CSS class and any CSS class bound from the parent calling the component.
View this fiddle for illustration: https://jsfiddle.net/cicsolutions/b6rnaw25/
If a component has a class on its root element and that class is a string, Vue's class binding places the class at the beginning of the resulting bound class list. This logic follows as the component sets the base CSS class and users can customize styles by adding classes to the HTML element. Vue then binds/joins these classes together.
In cases where a dynamic CSS class (not a static string) is used, Vue positions the component's root element class at the end of the bound class list.
I am developing a component for wider use, aiming to set my component class on the root element with the option for others to override styles by simply adding their class to the component tag.
The root element class needs to be dynamic, requiring the utilization of an array or object for class binding.
Why does Vue place the component's root CSS class at the beginning for static classes and at the end for dynamic classes? While it may seem peculiar, there could be intentional reasons behind it that are not clear at first glance.
Regardless, how can I ensure that my component's root element class always appears first in the resulting bound class list when it needs to be a dynamic class?
Vue.directive('bound-class', (el) => {
const boundClass = el.attributes.class.nodeValue
const boundClassPrintout = document.createElement('div')
boundClassPrintout.innerHTML = 'Resulting Bound Class: ' + boundClass
el.appendChild(boundClassPrintout)
});
// STATIC CSS CLASS -> becomes 1st class in the bound class list (expected)
Vue.component('string-test', {
template: `<div class="string-class" v-bound-class><slot></slot></div>`
});
// DYNAMIC CSS CLASS -> becomes last class in the bound class list (unexpected)
Vue.component('array-test', {
template: `<div :class="['array-class']" v-bound-class><slot></slot></div>`
});
// DYNAMIC CSS CLASS -> becomes last class in bound class list (unexpected)
Vue.component('object-test', {
template: `<div :class="{ 'object-class': true }" v-bound-class><slot></slot></div>`
});
new Vue({
el: "#app",
computed: {
vueVersion() {
return Vue.version
}
}
})
body {
background: #20262E;
padding: 20px;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
}
h2 {
margin-bottom: 0.75rem;
}
<link href="https://cdn.jsdelivr.net/npm/tailwindcss/dist/tailwind.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>Vue version: {{ vueVersion }}</h2>
<string-test class="p-2 mb-2 border">Root class (string-class) at beginning (expected)</string-test>
<array-test class="p-2 mb-2 border">Root class (array-class) at end (unexpected)</array-test>
<object-test class="p-2 mb-2 border">Root class (object-class) at end (unexpected)</object-test>
</div>