Home > Net >  Vue.js Conditional and V-For not working as intended
Vue.js Conditional and V-For not working as intended

Time:09-17

Due to the Array.splice() function, only the first v-if is triggered even if the second one is the correct condition. When I console.log the photos object the number length of the 'photos' object gets smaller by increments of 4 until it's 0 hence why the first condition is hit. How do I stop this from happening to display the proper div ? Here is the body of my code :

<div v-if="(checkCount = 1)">
            <Splide :options="{ rewind: true }" aria-label="Carousel Pictures">
                <SplideSlide >
                    <div v-for="item in photos.splice(0, 4)" :key="item.id">
                        <a href="">
                            <img :src="item.img" alt="" />
                            <p>{{ item.text }}</p>
                        </a>
                    </div>
                </SplideSlide>
            </Splide>
        </div>
        <div v-else-if="(checkCount = 2)">
            <Splide :options="{ rewind: true }" aria-label="Carousel Pictures">
                <SplideSlide >
                    <div v-for="item in photos.splice(0, 4)" :key="item.id">
                        <a href="">
                            <img :src="item.img" alt="" />
                            <p>{{ item.text }}</p>
                        </a>
                    </div>
                </SplideSlide>
                <SplideSlide >
                    <div v-for="item in photos.splice(0, 4)" :key="item.id">
                        <a href="">
                            <img :src="item.img" alt="" />
                            <p>{{ item.text }}</p>
                        </a>
                    </div>
                </SplideSlide>
            </Splide>
        </div>

Here is the data and condition:

data() {
        return {
            photos: [
                {
                    img: "https://picsum.photos/300/300",
                    text: 1,
                },
                {
                    img: "https://picsum.photos/300/300",
                    text: 2,
                },
                {
                    img: "https://picsum.photos/300/300",
                    text: 3,
                },
                {
                    img: "https://picsum.photos/300/300",
                    text: 4,
                },
                {
                    img: "https://picsum.photos/300/300",
                    text: 5,
                },
                {
                    img: "https://picsum.photos/300/300",
                    text: 6,
                },
                {
                    img: "https://picsum.photos/300/300",
                    text: 7,
                },
                {
                    img: "https://picsum.photos/300/300",
                    text: 8,
                },
            ],
        };
    },
    computed: {
        checkCount() {
            if (this.photos.length <= 4) {
                return 1;
            } else if (this.photos.length > 5 && this.photos.length <= 8) {
                return 2;
            } else if (this.photos.length > 9 && this.photos.length <= 12) {
                return 3;
            } else {
                return 4;
            }
        },
    },

CodePudding user response:

This looks like an assigment not comparition:

checkCount = 1

try this instead:

checkCount == 1 or checkCount === 1

CodePudding user response:

Observations :

  • You are using assignment operator =, It should be comparison operator == or ===.
  • There is no property named as id in the item. I think it should be item.text instead of item.id as per your photos object.

Explanantion :

As per your current code, checkCount computed property will get the value based on the photos array length which is 8. Hence, as per the second condition, computed property will return 2.

But as you are splicing the photos array photos.splice(0, 4) inside the div. It will remove the 5 objects (from index 0 to index 4) from a photos array. Hence, In that case remaining objects will be only 3 and photos array length become 3 which trigger the computed property and will return 1. That's the reason at the end you will be only see the first condition div content.

Live Demo :

new Vue({
  el: '#app',
  data: {
    photos: [
      {
        img: "https://picsum.photos/300/300",
        text: 1,
      },
      {
        img: "https://picsum.photos/300/300",
        text: 2,
      },
      {
        img: "https://picsum.photos/300/300",
        text: 3,
      },
      {
        img: "https://picsum.photos/300/300",
        text: 4,
      },
      {
        img: "https://picsum.photos/300/300",
        text: 5,
      },
      {
        img: "https://picsum.photos/300/300",
        text: 6,
      },
      {
        img: "https://picsum.photos/300/300",
        text: 7,
      },
      {
        img: "https://picsum.photos/300/300",
        text: 8,
      },
    ]
  },
  computed: {
    checkCount() {
      if (this.photos.length <= 4) {
        return 1;
      } else if (this.photos.length > 5 && this.photos.length <= 8) {
        return 2;
      } else if (this.photos.length > 9 && this.photos.length <= 12) {
        return 3;
      } else {
        return 4;
      }
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div v-if="checkCount === 1">
    First Div
  </div>
  <div v-if="checkCount === 2">
    Second Div
    <div v-for="item in photos.splice(0, 4)" :key="item.text">
      <p>{{ item.text }}</p>
    </div>
  </div>
</div>

  • Related