根据数组中的对象属性生成带有头部的列表

时间:2019-05-29 21:44:07

标签: javascript arrays vue.js lodash

在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>

我已经使用lodash _.sortBy通过nationality属性对数组进行了排序,并且给了我一个按国籍排序的数组,但是我想添加一个具有国籍值的H2元素。

2 个答案:

答案 0 :(得分:1)

如果您有多个具有相同国籍的商品,并且想要将它们归类,请在_.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']
      );
    }
  }
})

请注意,以上两个示例均输出所需的标记。如果希望每个项目都有自己的包装器,请用HTML标记替换<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>

答案 1 :(得分:0)

考虑到数组是有序的,您可以这样做:

    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>