I'm sure this one's gonna be extremely easy for you guys. I am trying to make a simple list of posts with the post titles always visible, and when you click a specific post in the list, you get the post's body. I used v-show for that. However, when I click a specific post, the bodies of all of the posts appear, instead of just the one that I clicked.
Here's the template:
<template>
<div class="container">
<h1>My Posts</h1>
<ul class="list-group">
<li class="list-group-item" v-for="post in list">
<div @click="changeShow">
<h4>{{ post.title }}</h4>
<p v-show="show">{{ post.body }}</p>
<span v-show="show" class="label label-primary">ID: {{ post.userId }}</span>
</div>
</li>
</ul>
</div>
And the logic:
<script>
export default{
data(){
return{
msg:'hello vue',
list: [],
show: false
}
},
ready(){
this.fetchPostList();
},
methods:{
fetchPostList: function () {
var root = 'http://jsonplaceholder.typicode.com';
this.$http.get(root + '/posts').then(function (response) {
this.list = response.data;
})
},
changeShow: function () {
this.show = !this.show;
}
}
}
The v-show directive is a Vue. js directive used to toggle the display CSS property of a element with our data via inline styles. If the data is true it will make it visible else it will make it invisible.
Vue gives you a bunch of good ways to hide the element on the screen. When using v-if="false" the element isn't rendered at all in the DOM. When using v-show="false" the element is rendered in the DOM, however, Vue applies the inline style display: none that hides the element completely.
The key difference is that v-if conditionally renders elements and v-show conditionally displayselements. This means that v-if will actually destroy and recreate elements when the conditional is toggled. Meanwhile, v-show will always keep the element in the DOM and will only toggle its display by changing its CSS.
v-if is “real” conditional rendering because it ensures that event listeners and child components inside the conditional block are properly destroyed and re-created during toggles.
There's a few ways to approach this depending on your needs.
You can make each post it's own component, that way you can have show
be tied to each individual post instead of all of them.
Vue.component('post', {
template: '#post-template',
props: {
post: Object,
},
data() {
return {
show: false,
}
},
methods: {
toggleShow() {
this.show = !this.show
},
},
})
Then you can have use it like this:
<post v-for="post in posts" :post="post"></post>
If you just want one open you can pass an id
as a prop and show it based on that.
Vue.component('post', {
template: '#post-template',
props: {
post: Object,
selectedId: Number,
},
computed: {
show() {
return this.post.id === this.selectedId
},
},
})
Then you can do like
<post :selected-id="selectedId" :post="post" @click="selectedId = post.id"></post>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With