Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue.js v-show in a list

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

}

like image 482
Miodrag Nisevic Avatar asked Sep 29 '16 19:09

Miodrag Nisevic


People also ask

What is V-show in Vue JS?

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.

How do you show and hide in Vue?

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.

What is the difference between V-if and V-show?

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.

Does V-if destroy component?

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.


1 Answers

There's a few ways to approach this depending on your needs.

Multiple Open

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>

One Open

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>
like image 172
Bill Criswell Avatar answered Oct 06 '22 01:10

Bill Criswell