简体   繁体   中英

Understanding Vue.js CSS Class Binding Ordering

Can anyone help me understand how to control the ordering of a component root element css class and any css class that may be bound from the parent calling the component?

Here is a fiddle that depicts what I'm noticing (snippet example below): https://jsfiddle.net/cicsolutions/b6rnaw25/

You'll notice if you have a component with a class on its root element, if that class is a string, Vue's class binding places the class at the beginning of the resulting bound class list. This is what I would expect because because the component sets the base css class and then you can customize the styles when you use the component by adding classes to the component html element. Then Vue binds/joins the classes together.

In the next examples in the fiddle, I'm showing the use of a css class that is dynamic (ie not a static string). In these cases, Vue places the component's root element class at the end of the bound class list.

I'm working on a component that I hope others will use, so I'd like to set my component class on the root element, and then if anyone wants to override those styles, they can just add their own class on the component tag.

I also need the root element class to be dynamic, so I must use an array or an object to handle the class binding.

Does anyone know why Vue places the component root css class at the beginning for static classes and at the end for dynamic classes? That seems strange to me, but perhaps it's intentional for a reason that eludes me.

None the less, how would I go about ensuring that my component's root element class is always first in the resulting bound class list, when I need it 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 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 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> 

I suspect that there's no particular reason why Vue inserts static classes first; possibly it's just mirroring the order of the input parameters in the renderClass function.

Also the order of rule sets in CSS files matters; the order of class names in the class attribute of elements does not. And neither order has anything to do with the cascade , which refers to child elements inheriting styles from their parents. Perhaps you've confused that with the order of declarations within a block or within an inline style. In that case order does matter:

<p class="red blue">
    Order doesn't matter in the class attribute above. If
    the class styles contradict, whichever is defined last
    will win regardless of how they're ordered in the attribute.
</p>

<p class="blue red">
    This paragraph will be styled identically to the previous
    one, despite the change in class order.
</p>

<p style="color: red; color: blue">
    Order does matter here. The text color will be blue.
</p>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM