是否可以在 vuejs 中连接 class 属性?

Is it possible to concatenate class properties in vuejs?

一般问题: 我想知道是否可以根据条件连接 class 属性。请参阅 v-for 行中的伪代码。

我的用例:我想对齐所有在右侧具有偶数索引的图像。

如果我对父部分使用 flex flex-row-reverse,我会将图像右对齐。但是我不知道如何以不必为子元素重复代码的方式构造 class 。

<section
    v-for="(quote, index) of $frontmatter.quotes :class="lg:flex my-4 mx-12 overflow-auto" + {even: index % 2, odd: !(index % 2)}"
  >
    <img
      class="quote-image right rounded-full h-64 w-64 flex items-center justify-center shadow-md mx-auto lg:ml-16 lg:mr-10 mt-12"
      :src="$withBase(quote.image)"
    />

    <div class="px-8 pt-6">
        <h3 class="text-primary font-bold mb-4">
          {{ quote.title }}
        </h3>
      <p>
        {{ quote.text }}
      </p>
    </div>
  </section>

然后将 class 扩展名命名为:

.even {
   flex-row-reverse
}

目前,我使用这个结构 - 但是,我对此并不满意,因为我必须为子元素重复我的代码...

<section
        v-for="(quote, index) of $frontmatter.quotes"
        class= "my-16 mx-24 overflow-auto"
      >
      <div v-if="index % 2"
      class="lg:flex flex-row-reverse">
        <img
          class="quote-image rounded-full h-64 w-64 flex items-center justify-center shadow-md mx-auto lg:ml-16 lg:mr-10 mt-12"
          :src="$withBase(quote.image)"
        />
        <div class="px-8 pt-6">
          <blockquote>
            <h2 class="text-primary font-bold mb-4">
              {{ quote.title }}
            </h2>
          </blockquote>
          <p class="quote-text">
            {{ quote.text }}
          </p>
        </div>
      </div>
      <div v-else
        class="lg:flex">
        <img
          class="quote-image rounded-full h-64 w-64 flex items-center justify-center shadow-md mx-auto lg:ml-16 lg:mr-10 mt-12"
          :src="$withBase(quote.image)"
        />
        <div class="px-8 pt-6">
          <blockquote>
            <h2 class="text-primary font-bold mb-4">
              {{ quote.title }}
            </h2>
          </blockquote>
          <p class="quote-text">
            {{ quote.text }}
          </p>
        </div>
      </div>

      </section>

它应该看起来像:

由于您使用的是 classes,而不是 <b-img> 道具,也许您需要的 class 是 float-right 而不是 right

    <img v-if="index % 2"
      class="quote-image float-right rounded-full h-64 w-64 shadow-md mx-auto lg:ml-16 lg:mr-10 mt-12"
      :src="$withBase(quote.image)"
    />

首先,澄清一下我要回答的问题。给定以下代码:

<div v-if="index % 2" class="lg:flex flex-row-reverse">
  ... children ...
</div>
<div v-else class="lg:flex">
  ... identical children ...
</div>

有没有办法避免 v-if 并有条件地添加 flex-row-reverse class?

这里有多种选择。首先,属性 classstyle 具有特殊的行为,允许您指定同一属性的绑定副本和静态副本。您不能对其他属性执行此操作。例如

<div
  class="lg:flex"
  :class="{ 'flex-row-reverse': index % 2 }"
>

所以 class lg:flex 是作为静态添加的 class 而 flex-row-reverse 是有条件地添加的。 Vue 将适当地组合它们以创建完成的 DOM 个节点的 class 属性。

还有很多其他的写法。以下是一些值得思考的问题:

<div :class="{ 'lg:flex': true, 'flex-row-reverse': index % 2 }">
<div :class="['lg:flex', { 'flex-row-reverse': index % 2 }]">

数组可以嵌套任意深度。纯字符串将被视为要添加的 classes。对象将被视为条件 class 的集合,class 名称作为 属性 名称,条件为 属性 值。

所有这些都是利用 Vue 对有条件地添加 classes 的支持。但是,绑定表达式只是任意的 JavaScript 因此您可以使用普通 JavaScript 语法应用条件性,而不是让 Vue 为您做。

这通常比较笨重。这必须是单个表达式,因此您不能使用 if/else。但是,您可以使用 ?: 代替:

<div :class="'lg:flex' + (index % 2 ? ' flex-row-reverse' : '')">

这些构建 classes 的各种方法的官方文档在这里:

https://vuejs.org/v2/guide/class-and-style.html#Binding-HTML-Classes