Reputation: 5863
I have a v-for
like so:
<p> User Responses(s):</p>
<template v-for="item in UserResponses">
<ol v-if="item.some_condition==item._is_true">
<li :name="item.id + '__UR'"> [[ item.some_variable_to_render ] ]] </li>
</ol>
</template>
Works great. However, what I would like to do is say No user responses
when the some_condition_is_true
fails, but if I add an v-else
the message (No user responses) will be printed in every loop, which is not desired ofcourse. How does one solve this problem?
To this end, I wondered if I could test if the element item.id + '__UR'" is present and if not add an element with text saying
No user responses`
I am not sure however that this is the correct way to go about this.
EDIT
Just to reiterate: using v-if
before v-for
is not an option since the object being iterated on is a nesed JSON which then is filtered through some vuejs filters, so yea, this is not an option.
Upvotes: 1
Views: 122
Reputation: 1
Using computed with v-if
:
ā¢ Sometimes, you might have a list of items that you want to filter based on a condition and then render the filtered list using v-if. In such cases, instead of putting the filtering logic directly in the template with v-if, you can use a computed property to create a filtered version of the list https://v3-migration.vuejs.org/breaking-changes/v-if-v-for.
ā¢ This approach separates the concerns of data processing and rendering, making the code more maintainable and potentially improving performance since the filtered list is only re-computed when the original list or the filter condition changes.
Here's an example of using a computed property with v-if:
<template>
<div>
<ul>
<!-- Use v-if to conditionally render items based on the computed property -->
<li v-for="item in filteredList" v-if="item.isVisible">
{{ item.name }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ name: 'Item 1', isVisible: true },
{ name: 'Item 2', isVisible: false },
// ... more items
],
};
},
computed: {
// Create a computed property for the filtered list
filteredList() {
return this.items.filter(item => item.isVisible);
},
},
};
</script>
Upvotes: -1
Reputation: 29092
It is possible you may be able to implement this using CSS:
ol + .no-responses {
display: none;
}
There's a full example below but the idea is simply to hide the message if it comes after an <ol>
. Tweak the selector to reflect your real use case.
I have tried to keep the template in my example exactly the same as the original code, with the addition of the relevant message and a couple of buttons for demo purposes.
new Vue({
el: '#app',
delimiters: ['[[', ']]'],
data () {
return {
UserResponses: []
}
},
methods: {
add () {
this.UserResponses.push(
{ some_condition: 3, _is_true: 3, id: 3, some_variable_to_render: 'A' },
{ some_condition: 3, _is_true: 4, id: 4, some_variable_to_render: 'B' },
{ some_condition: 4, _is_true: 4, id: 5, some_variable_to_render: 'C' },
{ some_condition: 5, _is_true: 5, id: 6, some_variable_to_render: 'D' }
)
},
clear () {
this.UserResponses.splice(0)
}
}
})
ol + .no-responses {
display: none;
}
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="app">
<p>User Responses(s):</p>
<template v-for="item in UserResponses">
<ol v-if="item.some_condition==item._is_true">
<li :name="item.id + '__UR'"> [[ item.some_variable_to_render ]] </li>
</ol>
</template>
<p class="no-responses">No user responses</p>
<button @click="add">Add values</button>
<button @click="clear">Clear values</button>
</div>
Upvotes: 1
Reputation: 20430
note that boolVar
corresponds to your actual object key that contains the bools
let model.flag = true
function foo(val) => {
model.flag = val
return val
}
<p> User Responses(s):</p>
<template>
<div v-if="model.flag">
<div v-for="item in UserResponses" >
<ol v-if="foo(item.Boolvar)" >
<li :name="item.id + '__UR'"> [[ item.some_variable_to_render ] ]] </li>
</ol>
</div>
</div>
<h1 v-else>No user responses š¢</h1>
</template>
Upvotes: 2