理解Vue.js CSS类绑定顺序

5

有人能帮我理解如何控制组件根元素的CSS类和从父组件调用组件的任何CSS类的排序吗?

这是一个演示我注意到的问题的fiddle(以下是片段示例): https://jsfiddle.net/cicsolutions/b6rnaw25/

您会注意到,如果组件具有其根元素上的类,则如果该类是字符串,则Vue的类绑定将该类放在生成的绑定类列表的开头。这是我所期望的,因为组件设置了基本CSS类,然后您可以通过向组件HTML元素添加类来自定义样式。然后Vue将类绑定/连接在一起。

在fiddle中的下一个示例中,我展示了使用动态CSS类(即非静态字符串)的用法。在这些情况下,Vue将组件的根元素类放在绑定类列表的末尾。

我正在开发一个希望其他人使用的组件,因此我想在根元素上设置我的组件类,然后如果有人想要覆盖这些样式,他们可以只需在组件标记上添加自己的类。

我还需要根元素的类是动态的,所以我必须使用数组或对象来处理类绑定。

有人知道为什么Vue在静态类中将组件根css类放在开始处,在动态类中将其放在末尾吗?这对我来说似乎很奇怪,但也许出于某种原因而有意为之。

无论如何,当我需要它成为动态类时,我该如何确保我的组件根元素类始终位于结果绑定类列表中的第一位呢?

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>


1
  1. 您的fiddle链接已损坏。
  2. 如果我理解正确,您正在尝试控制添加到元素的CSS类的顺序。是这样吗?如果是这样,为什么要这样做?类的顺序没有任何影响。
- Stephen Thomas
fiddle链接已修复,感谢您的提醒!是的,您理解问题的正确。我也很好奇为什么Vue根据设置方式不同而以不同的方式处理类。Vue非常聪明,所以肯定有一个很好的原因。CSS类会级联,因此顺序绝对会产生影响。 - CICSolutions
很抱歉,你对CSS层叠的理解有误。请参考https://codepen.io/sathomas/pen/WmoaGw。 - Stephen Thomas
1个回答

3
我怀疑Vue之所以首先插入静态类,可能没有特定的原因;可能只是反映了renderClass函数中输入参数的顺序。

CSS文件中规则集的顺序也很重要;元素class属性中类名的顺序并不重要。这两种顺序都与cascade无关,后者指的是子元素从其父元素继承样式。也许你把它和块内或内联样式中声明的顺序混淆了。在那种情况下,顺序确实很重要:

<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>

谢谢!我很感激你详尽而有帮助的解释! - CICSolutions
你是怎么知道在哪里引用renderClass的?除了Vue文档和论坛之外,是否有更详细的架构阅读/文档可以解释这个问题?还是你只是在研究源文件? - CICSolutions
只是阅读源代码。不过,如果您正在寻找额外的信息,Vue Mastery有一系列关于Vue内部和架构的非常好的教程。 - Stephen Thomas
非常感谢!非常感谢您详细的解释 :) - Raviteja

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接