最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Adding some logic in v-for with v-if Vue - Stack Overflow

programmeradmin1浏览0评论

I have some json with below results

{
  "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"
    }
  ]
}

Now i want to render it on a page with some loop and conditional, like below

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

But instead of success, i got some error saying

5:99 error The 'modules' variable inside 'v-for' directive should be replaced with a puted 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 puted property that returns filtered array instead. You should not mix 'v-for' with 'v-if' vue/no-use-v-if-with-v-for

Actually i want to create the <div class="col-lg-3"> part to be dynamic based on the json, if size:1 mean to have col-lg-3 and if size:2 mean to have col-lg-6

Any explanation and suggestion will be appreciated. Thank you

I have some json with below results

{
  "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"
    }
  ]
}

Now i want to render it on a page with some loop and conditional, like below

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

But instead of success, i got some error saying

5:99 error The 'modules' variable inside 'v-for' directive should be replaced with a puted 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 puted property that returns filtered array instead. You should not mix 'v-for' with 'v-if' vue/no-use-v-if-with-v-for

Actually i want to create the <div class="col-lg-3"> part to be dynamic based on the json, if size:1 mean to have col-lg-3 and if size:2 mean to have col-lg-6

Any explanation and suggestion will be appreciated. Thank you

Share Improve this question edited Jun 25, 2020 at 5:24 aswzen asked Jun 25, 2020 at 5:08 aswzenaswzen 1,65234 silver badges48 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 4

eslint-plugin-vue was telling you to do this:

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

In your case, it can be simplified as

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

If it's essentially something with css classes, why don't you use v-bind:class or :class with your condition ?

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

But like said in the error message you'll certainly have to create a sub ponent and then use props on it

https://v2.vuejs/v2/guide/ponents-props.html

In case you have just two sizes:

You can use Computed Properties to achieve this requirement.

First, create two new puted properties like:

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

Now, you can easily loop through puted properties modulesSize1 && modulesSize2 like:

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

In case you have multiple sizes:

First, create a simple method like:

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

and then we can update template and use 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>

The v-if is essentially baked in to the v-for (if modules is empty nothing will render) so it's remended not to use them in bination. If you need it for a separate condition, like you do here, then you'll have to move your v-for on to the <img> itself.

You also won't be able to use data.size this way so you'd have to use something like v-if="modules[0].size == 1" etc.

Edit

@Palash answer is probably the more efficient way to solve this.

Edit 2

@r0ulito and @xianshenglu also makes a really good point, if it's just a class issue, use v-bind.

发布评论

评论列表(0)

  1. 暂无评论