Создайте список с заголовком на основе свойства объекта в массиве - PullRequest
0 голосов
/ 30 мая 2019

В Vue я пытаюсь создать список, основанный на свойстве объекта.У меня есть массив из хранилища vuex, который выглядит следующим образом:

const array = [
 { 
   name: "British title string"
   nationality: "British"
 },
 { 
   name: "Another title"
   nationality: "American"
 },
 { 
   name: "Name"
   nationality: "Dutch"
 },
{ 
   name: "Another american item"
   nationality: "American"
 },
];

Я хочу получить такой вывод с использованием v-for:

<h2>British</h2>
<ul>
   <li>British title string</li>
</ul>

<h2>American</h2>
<ul>
   <li>Another title</li>
   <li>Another american item</li>
</ul>

<h2>Dutch</h2>
<ul>
   <li>Name</li>
</ul>

У меня уже естьотсортировал массив по свойству nationality, используя lodash _.sortBy, и он дал мне массив, отсортированный по национальности, но я хочу добавить элемент H2 со значением национальности.

Ответы [ 2 ]

1 голос
/ 30 мая 2019

Если у вас есть несколько предметов одной национальности и вы хотите сгруппировать их, используйте _.groupBy() перед _.sortBy():

Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
  el: '#app',
  template: '#appTemplate',
  data: () => ({
    rawData: [{
        name: "British title string",
        nationality: "British"
      },
      {
        name: "Another title",
        nationality: "American"
      },
      {
        name: "Name",
        nationality: "Dutch"
      },
      {
        name: "Another american item",
        nationality: "American"
      }
    ]
  }),
  computed: {
    groupedItems() {
      return _.sortBy(
        _.map(
          _.groupBy(this.rawData, 'nationality'), 
          items => ({
            items,
            nationality: items[0].nationality
          })
        ), 
        ['nationality']
      );
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
<script type="text/template" id="appTemplate">
  <div>
    <template v-for="group in groupedItems">
      <h2 v-text="group.nationality" />
      <ul>
        <li v-for="(item, index) in group.items" :key="index" v-text="item.name" />
      </ul>
    </template>
  </div>
</script>
<div id="app"></div>

Для удобства и удобства чтения данных я отобразил первый элемент nationality в качестве национальности группы (и назвал сгруппированные элементы items), но вы могли бы вместо этого напрямую использовать национальность элемента 0 в шаблоне.
Чтобы продемонстрировать, вот как это выглядело бы:

Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
  el: '#app',
  template: '#appTemplate',
  data: () => ({
    rawData: [{
        name: "British title string",
        nationality: "British"
      },
      {
        name: "Another title",
        nationality: "American"
      },
      {
        name: "Name",
        nationality: "Dutch"
      },
      {
        name: "Another american item",
        nationality: "American"
      }
    ]
  }),
  computed: {
    groupedItems() {
      return _.sortBy(
        _.groupBy(this.rawData, 'nationality'), 
        ['0.nationality']
      );
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
<script type="text/template" id="appTemplate">
  <div>
    <template v-for="grouped in groupedItems">
      <h2 v-text="grouped[0].nationality" />
      <ul>
        <li v-for="(item, index) in grouped" :key="index" v-text="item.name" />
      </ul>
    </template>
  </div>
</script>
<div id="app"></div>

Обратите внимание, что оба приведенных выше примера выводят требуемую разметку. Если вы хотите, чтобы у каждого элемента была своя собственная оболочка, замените <template> на HTML-тег и добавьте ключи. то есть:

<article v-for="(grouped, key) in groupedItems" :key="key">
0 голосов
/ 30 мая 2019

Вы можете сделать это, учитывая, что массив упорядочен:

    const array = [
      {
        name: "Another title",
        nationality: "American"
      },
      {
        name: "Another american item",
        nationality: "American"
      },
      {
        name: "British title string",
        nationality: "British"
      },
      {
        name: "Name",
        nationality: "Dutch"
      },

    ];
    const arrayAux = [];
    var j = 0;
    for (var i = 0; i < array.length;) {
      console.log(array[i].name);
      arrayAux.push({
        nationality: array[i].nationality,
        names: [array[i].name]
      });
      i++;
      while ( i < array.length && array[i].nationality === array[i - 1].nationality) {
        arrayAux[j].names.push(array[i].name);
        i++;
      }
      j++;

    }
    console.log(arrayAux);

В html:

<div v-for="item in arrayAux">
  <h2>{{ item.nationality }}</h2>
  <ul>
    <li v-for="n in item.names">
      {{ n.name }}
    </li>
  </ul>
</div>
...