【问题标题】:How to group data from attributes using for loops in VueJS如何在 VueJS 中使用 for 循环对属性中的数据进行分组
【发布时间】:2018-09-23 21:27:41
【问题描述】:

我正在尝试研究如何使用 VueJS 中的 for 循环在两个级别上对数据进行分组

作为一个例子,我有一个带有以下数据的 VueJS 应用程序:

cars: [{
  "make": "Ford",
  "model": "Mustang"
}, {
  "make": "Ford",
  "model": "Thunderbird"
}, {
  "make": "Ford",
  "model": "Fairlane"
}, {
  "make": "Chevrolet",
  "model": "Camaro"
}, {
  "make": "Chevrolet",
  "model": "Chevelle"
}, {
  "make": "Plymouth",
  "model": "Barracuda"
}]

使用 for 循环遍历汽车很简单:

<div v-for="car in cars">
  <div>Make: {{ car.make }}</div>
  <div>Model: {{ car.model }}</div>  
</div>

但如果我想按品牌对模型进行分组怎么办?我追求的输出是:

Ford
  Mustang
  Thunderbird
  Fairlane
Chevrolet
  Camaro
  Chevelle
Plymouth
  Barracuda

在 VueJS 中最好的方法是什么?

【问题讨论】:

    标签: vue.js


    【解决方案1】:

    @DigitalDrifter 有一个很好的解决方案,但您可能会发现以下内容更易于阅读。不过,它的效率较低,所以我绝对不会将它用于大型收藏(例如数千辆汽车)。

    computed: {
        makes() {
            const makes = new Set();
            this.cars.forEach(car => makes.add(car.make);
            return Array.from(makes); 
        }
    },
    methods: {
        models(make) {
            return this.cars
                .filter(car => car.make === make)
                .map(car => car.model);
        }
    }
    

    在模板中

    <div v-for="(make, index) in makes" :key="index">
        <p>Make: {{ make }}</p>
        <ul>
            <li v-for="(model, innerIndex) in models(make)" :key="innerIndex">
                {{ model }}
            </li>
        </ul>
    </div>
    

    【讨论】:

    • 谢谢。我发现这更容易理解。
    • 答案有语法错误,计算例程缺少')'。
    【解决方案2】:

    您可以在计算属性中使用reduce

    computed: {
      groups () {
        return this.cars.reduce((carry, current) => {
          if (carry.hasOwnProperty(current.make) && Array.isArray(carry[current.make])) {
            carry[current.make].push(current.model)
          } else {
            Object.assign(carry, { [current.make]: [current.model] })
          }
          return carry
        }, {})
      }
    }
    

    模板可以循环分组如下:

    <div v-for="(make, index) in Object.keys(groups)" :key="index">
      <p>Make: {{ make }}</p>
      <ul>
      <li v-for="(model, innerIndex) in groups[make]" :key="innerIndex">
        {{ model }}
      </li>
      </ul>
    </div>
    

    【讨论】:

      【解决方案3】:

      为什么要在计算上浪费这么多 cpu 而不是做一些具有 ui 友好结构的数据按摩?

      props: { 
        cars: Array 
      },
      data() {
        return {
          makes: _.groupBy(this.cars, 'make'); // _.groupBy is a lodash function
        };
      },
      methods: {
        // some CRUD methods
        add() {},
        update() {},
        delete() {},
        reconstruct() {
          var result = [];
          Object.keys(this.makes).forEach(key => {
            result.push(...this.makes[key]);
          });
          return result;
        }
      }
      
      <div v-for="(make, key) in makes" :key="key">
      <p>Make: {{ make }}</p>
      <ul>
          <li v-for="(car, index) in make" :key="index">
              {{ car.model }}
          </li>
      </ul>
      </div>
      

      您只需要在与 API 对话时进行构造/解构。

      【讨论】:

      • 可以导入单个 lodash 函数。使用计算也是“至少”两个循环,一个用于从 API 响应接收数据,一个用于执行任何 CRUD 方法。
      【解决方案4】:

      你可以利用computed属性如下,(运行这段代码sn-p查看):

      var app = new Vue({
        el: "#app",
        data: {
            cars : [{
        "make": "Ford",
        "model": "Mustang"
      }, {
        "make": "Ford",
        "model": "Thunderbird"
      }, {
        "make": "Ford",
        "model": "Fairlane"
      }, {
        "make": "Chevrolet",
        "model": "Camaro"
      }, {
        "make": "Chevrolet",
        "model": "Chevelle"
      }, {
        "make": "Plymouth",
        "model": "Barracuda"
      }]
        },
        computed: {
            groupedMakes() {
                var makes={};
                this.cars.forEach((item)=>{
               if(makes[item.make]==undefined){
                    makes[item.make]=[];
                    makes[item.make].push(item.model)
                      }
                else{
                  makes[item.make].push(item.model);
      
                  }
                 });
               
                 return makes;
            }
        }
      })
      <div id="app">
          <div v-for="(make,index) in groupedMakes">
              <h3>{{index}}</h3>
               <ul>
                  <li v-for="model in make">
                  {{model}}
                  </li>
               </ul> 
          </div>
         
      </div>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-05-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多