使用 v-if Vue 在 v-for 中添加一些逻辑

Adding some logic in v-for with v-if Vue

我有一些 json 结果如下

{
  "module": [
    {
      "id": 1,
      "title": "Module 1",
      "type": "URL",
      "size": 1,
      "image": "https://localhost/image1.png"
    },
    {
      "id": 2,
      "title": "Module 2",
      "type": "YOUTUBE",
      "size": 2,
      "image": "https://localhost/image2.png"
    }
  ]
}

现在我想在带有一些循环和条件的页面上呈现它,如下所示

<template>
  <section class="page-section homescreen mt-4">
    <div class="container">
        <div class="row">
          <div class="col-lg-3" v-bind:key="data.index" v-for="data in modules" v-if="data.size == 1">
              <img class="img-fluid" :src="`${data.image}`" :alt="`${data.title}`" />
          </div>
          <div class="col-lg-6" v-bind:key="data.index" v-for="data in modules" v-if="data.size == 2">
              <img class="img-fluid" :src="`${data.image}`" :alt="`${data.title}`" />
          </div>
        </div>
    </div>
  </section>
</template>

<script>
export default {
  data() {
    return {
      modules: [
        {
          "id": 1,
          "title": "Module 1",
          "type": "URL",
          "size": 1,
          "image": "https://localhost/image1.png"
        },
        {
          "id": 2,
          "title": "Module 2",
          "type": "YOUTUBE",
          "size": 2,
          "image": "https://localhost/image2.png"
        }
      ]
    };
  }
};
</script>

但是我没有成功,而是收到一些错误提示

5:99 error The 'modules' variable inside 'v-for' directive should be replaced with a computed property that returns filtered array instead. You should not mix 'v-for' with 'v-if' vue/no-use-v-if-with-v-for
8:99 error The 'modules' variable inside 'v-for' directive should be replaced with a computed property that returns filtered array instead. You should not mix 'v-for' with 'v-if' vue/no-use-v-if-with-v-for

实际上我想根据 json 创建动态的 <div class="col-lg-3"> 部分,如果 size:1 意味着有 col-lg-3 如果 size:2意思是 col-lg-6

如有任何解释和建议,我们将不胜感激。 谢谢

v-if 本质上是嵌入到 v-for 中的(如果 modules 为空,则不会呈现任何内容)因此建议不要将它们组合使用。如果你需要它作为一个单独的条件,就像你在这里做的那样,那么你必须将你的 v-for 移到 <img> 本身。

您也无法以这种方式使用 data.size,因此您必须使用 v-if="modules[0].size == 1"

编辑

@Palash 的回答可能是解决这个问题的更有效方法。

编辑 2

@r0ulito 和@xianshenglu 也提出了一个非常好的观点,如果它只是一个 class 问题,请使用 v-bind。

如果您只有两种尺码:

您可以使用Computed Properties来达到这个要求。

首先,创建两个新的计算属性,例如:

computed: {
  modulesSize1: function() {
    return this.modules.filter(x => x.size == 1)
  },
  modulesSize2: function() {
    return this.modules.filter(x => x.size == 2)
  }
}

现在,您可以轻松循环计算属性 modulesSize1 && modulesSize2,例如:

<div class="row">
  <div class="col-lg-3" v-bind:key="data.index" v-for="data in modulesSize1" >
    <img class="img-fluid" :src="`${data.image}`" :alt="`${data.title}`" />
  </div>
  <div class="col-lg-6" v-bind:key="data.index" v-for="data in modulesSize2" >
    <img class="img-fluid" :src="`${data.image}`" :alt="`${data.title}`" />
  </div>
</div>

如果您有多种尺码:

首先,创建一个简单的方法,如:

methods: {
  getClass: function(size) {
    return `col-lg-${size * 3}`
  },
}

然后我们可以更新模板并使用 Class Bindings,例如:

<div :class="getClass(data.size)" :key="data.index" v-for="data in modules">
  <img class="img-fluid" :src="`${data.image}`" :alt="`${data.title}`" />
</div>

如果本质上是 css 类,你为什么不使用 v-bind:class:class 来满足你的条件?

https://vuejs.org/v2/guide/class-and-style.html

但是就像错误消息中所说的那样,您肯定必须创建一个子组件,然后在其上使用 props

https://vuejs.org/v2/guide/components-props.html

eslint-plugin-vue 告诉你这样做:

<div class="col-lg-3" v-bind:key="data.index" v-for="data in modules.filter(o=>o.size == 1)">
    <img class="img-fluid" :src="`${data.image}`" :alt="`${data.title}`" />
</div>
<div class="col-lg-6" v-bind:key="data.index" v-for="data in modules.filter(o=>o.size == 2)">
    <img class="img-fluid" :src="`${data.image}`" :alt="`${data.title}`" />
</div>

你的情况可以简化为

<div :class="'col-lg-'+data.size*3" v-bind:key="data.index" v-for="data in modules">
    <img class="img-fluid" :src="`${data.image}`" :alt="`${data.title}`" />
</div>