Vue.js — показать больше объектов из массива, если они имеют одинаковый заголовок

#arrays #vue.js

#массивы #vue.js

Вопрос:

У меня есть массив объектов:

 [{ 
   title: 'foo'
   id: 1,
   name: 'anne'
 },
  
 { 
   title: 'example',
   id: 2,
   name: 'anne'
 },
 { 
   title: 'ex',
   id: 3,
   name: 'deb'
 }]
  

На странице уже отображается первый объект:

 { 
   title: 'foo'
   id: 1,
   name: 'anne'
 },
 
 <div class="essay">
   <p class="title" >{{ selectedItem.title }}</p>
   <p class="id">{{ selectedItem.id }}</p>
   <p class="name"> {{ selectedItem.name }} </p>
 </div>
  

selectedItem происходит из created() жизненного цикла

Каков наилучший способ отображения объекта с тем же именем?

Я хочу иметь кнопку, при нажатии на которую будет отображаться другой заголовок из имени 'anne' пользователя.

Комментарии:

1. На странице уже отображается первый объект как вы это сделали?

2. Пожалуйста, добавьте свой код для компонента, который показывает один объект, тогда я смогу понять проблему

3. готово, дайте мне знать, если потребуется больше

Ответ №1:

Попробуйте получить отфильтрованный массив.

 created() {
  this.selectedItem = arr.filter(item => item.name === 'anne');
  // arr is the array source variable.
}
  
  <div v-for="item in selectedItem" :key="item.id" class="essay">
   <p class="title" >{{ selectedItem.title }}</p>
   <p class="id">{{ selectedItem.id }}</p>
   <p class="name"> {{ selectedItem.name }} </p>
 </div>
  

Ответ №2:

Я сделал фрагмент, возможно, это поможет вам 🙂

Нам нужно где-то хранить состояние, поэтому я создал owners переменную со shown счетчиком.

Существует также вычисляемое свойство, которое группирует элементы по владельцам.

Может быть, есть более простой метод, но…

 new Vue({
  el: '#app',
  data: {
    items: [
      { owner: "John", name: "Box" },
      { owner: "John", name: "Keyboard" },
      { owner: "John", name: "Plate" },
      { owner: "Ann", name: "Flower" },
      { owner: "Ann", name: "Cup" }
    ],
    owners: {},
  },
  methods: {
    more(owner) {
      if (this.owners[owner].shown < this.items.filter(i => i.owner == owner).length) {
        this.owners[owner].shown  ;
      }
    }
  },
  computed: {
    ownersItems() {
      let map = {};
      this.items.forEach(i => {
        map[i.owner] = map[i.owner] || [];
        if (this.owners[i.owner].shown > map[i.owner].length) {
          map[i.owner].push(i);
        }
      });
      return map;
    },
  },
  created() {
    let owners = {};
    this.items.forEach(i => {
      owners[i.owner] = owners[i.owner] || {};
      owners[i.owner].shown = 1;
    });
    this.owners = owners;
  }
})  
 #app {
  font-family: sans-serif;
  padding: 1rem;
}
.header {
  font-weight: bold;
  margin-bottom: .5rem;
}
sup {
  background: #000;
  color: #fff;
  border-radius: .15rem;
  padding: 1px 3px;
  font-size: 75%;
}
.btn {
  padding: .25rem .5rem;
  border: 1px solid #ddd;
  background: #eee;
  border-radius: .15rem;
  margin: 2px;
  cursor: pointer;
}  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <div class="header">Owners</div>
  <template v-for="(cfg, owner) in owners">
    <strong>{{ owner }} <sup>{{cfg.shown}}</sup>:</strong>
    <a v-for="(item, i) in ownersItems[owner]" :key="`${owner}_${i}`" @click="more(owner)" class="btn">{{ item.name }}</a>
    |
  </template>
</div>