admin管理员组

文章数量:1277270

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 = '';
            this.$http.get(root + '/posts').then(function (response) {
                this.list = response.data;
            })
        },
        changeShow: function () {
            this.show = !this.show;
        }
    }

}

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.';
            this.$http.get(root + '/posts').then(function (response) {
                this.list = response.data;
            })
        },
        changeShow: function () {
            this.show = !this.show;
        }
    }

}

Share Improve this question asked Sep 29, 2016 at 19:39 Miodrag NisevicMiodrag Nisevic 1111 gold badge2 silver badges7 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

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

Multiple Open

You can make each post it's own ponent, that way you can have show be tied to each individual post instead of all of them.

Vue.ponent('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.ponent('post', {
  template: '#post-template',
  props: {
    post: Object,
    selectedId: Number,
  },
  puted: {
    show() {
      return this.post.id === this.selectedId
    },
  },
})

Then you can do like

<post :selected-id="selectedId" :post="post" @click="selectedId = post.id"></post>

I cheated in a different way. Just added a show property to each post and toggled that.

new Vue({
  el: 'body',
  data: {
    list: []
  },
  ready: function() {
    this.fetchPostList()
  },
  methods: {
    fetchPostList: function() {
      setTimeout(function() {
        this.list.push({
          title: 'First Post',
          body: 'This is the first Post',
          userId: 'Joe',
          show: false
        });
        this.list.push({
          title: 'Second Post',
          body: 'This is the second Post',
          userId: 'Joe',
          show: false
        });
        this.list.push({
          title: 'Third Post',
          body: 'This is the third Post',
          userId: 'Joe',
          show: false
        });
      }.bind(this), 2000);
    },
    changeShow: function(idx) {
      this.list[idx].show = !this.list[idx].show;
    }
  }
});
<link href="//cdnjs.cloudflare./ajax/libs/skeleton/2.0.4/skeleton.min.css" rel="stylesheet" />
<script src="//cdnjs.cloudflare./ajax/libs/vue/1.0.26/vue.min.js"></script>
<div class="container">
  <h1>My Posts</h1>
  <ul class="list-group">
    <li class="list-group-item" v-for="post in list">
      <div @click="changeShow($index)">
        <h4>{{ post.title }}</h4>
        <p v-show="post.show">{{ post.body }}</p>
        <span v-show="post.show" class="label label-primary">ID: {{ post.userId }}</span>
      </div>
    </li>
  </ul>
</div>

First of all, the method that I will give an example is not useful, but I am writing to show that there is such a way.

for example

<script>
export default {
  data: {
    isShow: false,
    postUserId: null,
  },
};
</script>
<template>
  <div class="container">
    <h1>My Posts</h1>
    <ul class="list-group">
      <li class="list-group-item" v-for="post in list">
        <div @click="postUserId = post.userId; isShow = !isShow">
          <h4>{{ post.title }}</h4>
          <p v-show="show">{{ post.body }}</p>
          <span v-show="isShow && postUserId == post.userId" class="label label-primary">ID: {{ post.userId }}</span>
        </div>
      </li>
    </ul>
  </div>
</template>

本文标签: javascriptVuejs vshow in a listStack Overflow