Home > Mobile >  How to render list with different order from array object in vue js?
How to render list with different order from array object in vue js?

Time:10-12

I get the data from server something like this way:

    "cells": [
        {
          "consultingBudgetHeadName": "Available hours",
          "value": 1806,
          "valueMap": "1 806"
        },
        {
          "consultingBudgetHeadName": "Available customer hours",
          "value": 1773.2,
          "valueMap": "1 773,20"
        },
        {
          "consultingBudgetHeadName": "Absence hours",
          "value": 32.8,
          "valueMap": "32,80"
        },
        {
          "consultingBudgetHeadName": "Available hours project",
          "value": -7092.8,
          "valueMap": "-7 092,80"
        },
        {
          "consultingBudgetHeadName": "Average price",
          "value": 0,
          "valueMap": "0"
        },
        {
          "consultingBudgetHeadName": "Agreement hours",
          "value": 8866,
          "valueMap": "8 866"
        },
        {
          "consultingBudgetHeadName": "Utilization agreements %",
          "value": 500,
          "valueMap": "500"
        }
      ]

Now, if I render a list this way:

<template v-for="(cell, index) in cells">
   <li>
      {{ cell.consultingBudgetHeadName }}
   </li>
</template>

It will show the output this way:

  • Available hours
  • Available customer hours
  • Absence hours
  • Available hours project
  • Average price
  • Agreement hours
  • Utilization agreements %

But I need the order in a different way than the order of the array. I want my order will be like this:

  • Available hours
  • Absence hours
  • Available customer hours
  • Agreement hours
  • Available hours project
  • Average price
  • Utilization agreements %

So, instead of dynamic rendering, I took the index of the array element and render the element this way:

<ul v-for="(row, rowIndex) in data.rows">
   <li>{{ row.cells[0].consultingBudgetHeadName }}</li>
   <li>{{ row.cells[2].consultingBudgetHeadName }}</li>
   <li>{{ row.cells[1].consultingBudgetHeadName }}</li>
   <li>{{ row.cells[5].consultingBudgetHeadName }}</li>
   <li>{{ row.cells[3].consultingBudgetHeadName }}</li>
   <li>{{ row.cells[4].consultingBudgetHeadName }}</li>
   <li>{{ row.cells[6].consultingBudgetHeadName }}</li>
</ul>

But I don't think this would be a good idea as index number can be changed at the database any time. So, what's the good way to achieve those?

CodeSandbox Demo

CodePudding user response:

You can map your array and return it sorted with computed property:

const mappedCells = new Map([["Available hours", 1], ["Available customer hours", 3], ["Absence hours", 2], ["Available hours project", 5], ["Average price", 6], ["Agreement hours", 4], ["Utilization agreements %", 7]])
new Vue({
  el: "#demo",
  data() {
    return {
      "cells": [{"consultingBudgetHeadName": "Available hours", "value": 1806, "valueMap": "1 806"}, {"consultingBudgetHeadName": "Available customer hours", "value": 1773.2, "valueMap": "1 773,20"}, {"consultingBudgetHeadName": "Absence hours", "value": 32.8, "valueMap": "32,80"}, {"consultingBudgetHeadName": "Available hours project", "value": -7092.8, "valueMap": "-7 092,80"},  {"consultingBudgetHeadName": "Average price", "value": 0, "valueMap": "0"}, {"consultingBudgetHeadName": "Agreement hours", "value": 8866, "valueMap": "8 866"}, {"consultingBudgetHeadName": "Utilization agreements %", "value": 500, "valueMap": "500"}]
    }
  },
  computed: {
    sortedCells() {
      return this.cells.map(c => {
        c.nr = mappedCells.get(c.consultingBudgetHeadName)
        return c
      }).sort((a, b) => (a.nr > b.nr) ? 1 : -1)
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
  <li v-for="(cell, i) in sortedCells" :key="i">
      {{ cell.consultingBudgetHeadName }}
   </li>
</div>

CodePudding user response:

I think the better solution is to have an extra field in the database for index of the item, and then in the front end when you retrieve the data you can sort the list according to that field.

For example

 "cells": [
        {
          "consultingBudgetHeadName": "Available hours",
          "value": 1806,
          "valueMap": "1 806",
          "order": 1,
        },
        {
          "consultingBudgetHeadName": "Available customer hours",
          "value": 1773.2,
          "valueMap": "1 773,20",
          "order": 3,
        },
        {
          "consultingBudgetHeadName": "Absence hours",
          "value": 32.8,
          "valueMap": "32,80",
          "order": 2,
        },
        {
          "consultingBudgetHeadName": "Available hours project",
          "value": -7092.8,
          "valueMap": "-7 092,80",
          "order": 6,
        },
        {
          "consultingBudgetHeadName": "Average price",
          "value": 0,
          "valueMap": "0",
          "order": 4,
        },
        {
          "consultingBudgetHeadName": "Agreement hours",
          "value": 8866,
          "valueMap": "8 866",
          "order": 5,
        },
        {
          "consultingBudgetHeadName": "Utilization agreements %",
          "value": 500,
          "valueMap": "500",
          "order": 7,
        }
      ]

Then set a computed property for the sorted cells.

computed: {
  sortedCells() {
     return this.cells.sort((a, b) => a.order - b.order)
  }
}
  • Related