简体   繁体   中英

Vue list item on click details

I have this Vue app

var app = new Vue({
  el: '#main',
  delimiters: ['${', '}'],
  data () {
      posts: [
          {
            id: 1,
            title: 'Post title 1',
            description: 'Post description 1'
          },
          {
            id: 2,
            title: 'Post title 2',
            description: 'Post description 2'
          },
          {
            id: 3,
            title: 'Post title 3',
            description: 'Post description 3'
          }
      ],
  },
  methods: {
      getPostData: function (event) {

      }
  }
});

 <div id="main">
  <ul>
    <li v-for="(post, index) in posts"><a @click="getPostData">${ post.title }</a></li>
  </ul>
</div>
Here go description from clicked item

I want to click on an item in the list and display description from this item in #item-description div.

How I program this getPostData to grab description from an item on which I click.

Tnx

<div id="main">
  <ul>
     <li v-for="(post, index) in posts"><a @click="getPostData(post.description)">${ post.title }</a></li>
  </ul>
</div>

 methods: {
   getPostData: function (postDesc) {
     // you got the post Desc
   }
 }

You need to somehow store the currently selected item or description. You could do this by calling a method from your template, passing by the item as a parameter. Eg like this:

var app = new Vue({
    el: '#main',
    data() {
        return {
            posts: [{
                id: 1,
                title: 'Post title 1',
                description: 'Post description 1'
            }, {
                id: 2,
                title: 'Post title 2',
                description: 'Post description 2'
            }, {
                id: 3,
                title: 'Post title 3',
                description: 'Post description 3'
            }],
            currentDescription: null
        };
    },
    methods: {
        setDescription(item) {
            this.currentDescription = item.description;
        }
    }
});

<div id="main">
  <ul>
    <li v-for="(post, index) in posts">
      <a @click="setDescription(post)">${ post.title }</a>
    </li>
  </ul>
</div>

<div id="item-description">{{ currentDescription }}</div>

If you want to asynchronously fetch new data on a click, you could fetch the data directly in the setDescription method.


EDIT:

It's probably also better to store the ID of the post than the description itself. In this case, you have access to the whole post instead of just the description. You can then also check if the current <li> is active and so on. Here is an example of this. In the example, I've used computed properties, which can then be accessed like regular properties. They are derived from the current state. So, currentPost always gives you the currently selected post if the active ID is set. The currentDescription then reads the description of the currentPost . You can access these properties the same way as regular properties of the state.

var app = new Vue({
    el: '#main',
    data() {
        return {
            posts: [{
                id: 1,
                title: 'Post title 1',
                description: 'Post description 1'
            }, {
                id: 2,
                title: 'Post title 2',
                description: 'Post description 2'
            }, {
                id: 3,
                title: 'Post title 3',
                description: 'Post description 3'
            }],
            currentId: null
        };
    },
    methods: {
        setCurrentId(id) {
            this.currentId = id;
        }
    },
    computed: {
        currentPost() {
           if (this.currentId !== null) {
               const currentPostInArray = this.posts.filter(post => {
                  return post.id === this.currentId;
               });
               if (currentPostInArray.length === 1) {
                   return currentPostInArray[0];
               }
           }
           return null;
        },
        currentDescription() {
            if (this.currentPost !== null) {
                return this.currentPost.description;
            }
            return null;
        }
    }
});

<div id="main">
  <ul>
    <li v-for="(post, index) in posts" :class="{ active: post.id === currentId }">
      <a @click="setCurrentId(post.id)">${ post.title }</a>
    </li>
  </ul>
</div>

<div id="item-description">{{ currentDescription }}</div>

Just as a side note: Storing the whole post as a copy in the data instead of just the ID is not recommended. By using a computed property, you don't have to worry about this property, it will always be up to date. For instance, if you change the posts array and remove the currently selected post from it, the currentPost will lead to a null value, without updating anything else. Or in the case of changing the description: The computed property always gives you the correct item (with the updated description).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM