【问题标题】:Adding some logic in v-for with v-if Vue使用 v-if Vue 在 v-for 中添加一些逻辑
【发布时间】:2020-10-15 11:49:09
【问题描述】:

我有一些带有以下结果的 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 错误 'v-for' 指令中的 'modules' 变量应该是 替换为返回过滤数组的计算属性。 您不应该将 'v-for' 与 'v-if' 混合使用 vue/no-use-v-if-with-v-for
8:99 错误“v-for”指令中的“modules”变量应该是 替换为返回过滤数组的计算属性。 你不应该混合 'v-for' 和 'v-if' vue/no-use-v-if-with-v-for

实际上我想创建基于 json 的 &lt;div class="col-lg-3"&gt; 部分是动态的,如果 size:1 意味着拥有 col-lg-3 并且如果 size:2 意味着拥有 col-lg-6

任何解释和建议将不胜感激。 谢谢

【问题讨论】:

    标签: javascript vue.js vue-component v-for


    【解决方案1】:

    v-if 本质上是嵌入到v-for 中(如果modules 为空,则不会呈现任何内容),因此建议不要将它们组合使用。如果您需要它用于单独的条件,就像您在此处所做的那样,那么您必须将您的 v-for 移动到 &lt;img&gt; 本身。

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

    编辑

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

    编辑 2

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

    【讨论】:

    • 它不在图像中,而是在 div 中,但无论如何我都会尝试它。更新:不可能,你能帮我一些 sn-p 吗?
    • 我更新了我的答案,因为我错过了你将无法以这种方式使用data.size
    • 如果你可以包含来自你的 axios 请求的数据,我会做一个 sn-p
    【解决方案2】:

    如果您只有两种尺寸:

    您可以使用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 like:

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

    【讨论】:

    • IMO 它不是真正可扩展的,想象一下如果在不久的将来他会有二十张不同大小的图片?他会复制那个 sn-p 二十次吗?
    【解决方案3】:

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

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

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

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

    【讨论】:

      【解决方案4】:

      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>
      

      【讨论】:

      • 这是可扩展的!不错的工作伙伴;)
      猜你喜欢
      • 1970-01-01
      • 2019-06-28
      • 2021-02-28
      • 2019-05-18
      • 1970-01-01
      • 2019-12-20
      • 2018-11-08
      • 2023-02-24
      • 2019-08-12
      相关资源
      最近更新 更多