'How to use v-if, v-else inside of v-for properly in Vuejs?
<template>
<div>
<div v-for="box in boxes" :key="box.id">
<BaseAccordian>
<template v-slot:title>{{ box.name }}</template>
<template v-slot:content>
<div v-for="paint in paints" :key="paint.id" class="line">
<div
v-if="
matchingdata.some(
(m) => m.boxid == box.boxid && m.paintid == paint.paintid
)
"
>
<StatusComponent
:box="box"
:paint="paint"
:matchingdata="matchingdata"
/>
</div>
<!-- <div v-else>no data found</div> -->
</div>
</template>
</BaseAccordian>
</div>
</div>
</template>
When i click of each checkbox, i am loading relevant data from box,paint array. by checking in matchingdata. Array.
Now, i want to show like, if no data found onclick of checkbox, i want to display a message as "no data found"
Issue with the below code is, if i place v-if at top and v-for and v-else data at the last then only few data is displaying
Solution 1:[1]
the v-if checking ok and not ok should be written before the outside for loop
(before this row <div v-for="paint in paints" :key="paint.id" class="line">)
so the whole code should be somthing like this :
<div v-if="your data existence checking .....">
<div v-for="paint in paints" :key="paint.id" class="line">
<div
v-if="
matchingdata.some(
(m) => m.boxid == box.boxid && m.paintid == paint.paintid
)
"
>
<StatusComponent
:box="box"
:paint="paint"
:matchingdata="matchingdata"
/>
</div>
</div>
</div>
<div v-else>no data found</div>
Solution 2:[2]
The v-for is rendering for each 'box' in 'boxes', so for each box you should get a:
<BaseAccordian>
<template v-slot:title>{{ box.name }}</template>
<template v-slot:content>
<div v-for="paint in paints" :key="paint.id" class="line">
{...}
</div>
</template>
</BaseAccordian>
And for each paint in paints, this should render a div for each paint inside of every box.
The v-if and v-else-if and v-else will render their blocks conditionally on the predicates contained within them. I'm not sure where the array matchingdata comes from in your example, but if it contains an element that has the properties boxid and paintid that match box.boxid and paint.paintid then the predicate of matchingdata.some((m) => m.boxid == box.boxid && m.paintid == paint.paintid) will have been met and the associated div will be rendered; otherwise, the 'v-else' div will be rendered (if it were uncommented).
Your code will loop through each box in boxes, and for each box it will loop through each paint in paints to find an element in matchingdata that looks something like:
{
boxid: ...,
paintid: ...,
...,
}
The v-for and (v-if, v-else-if, v-else) blocks are not connected to each other. v-for represents a loop over which you will render an element for every item in the list. The v-if blocks will conditionally render elements to the page according to the predicates you define.
v-if, v-else-if, and v-else have to appear right after each other to be counted in the same logical block.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Moussab Kbeisy |
| Solution 2 | Drew L |
