[Vuejs]-How do I sort a computed property by a value?

2👍

Okay, let’s start from the beginning:

I think you should start with moving addToNamesArray() from computed to the methods. So you can be sure it’s only called once, computed will be called more often when your data changes.

your function sortNames should be moved to the computed field, like so:

mounted(){
    this.addToNamesArray()
},
computed: {
     sortedNames(){
          return this.namesArray.concat().sort((a,b) => a.firstName.localeCompare(b.firstName))
     }
},
methods: {
     addToNamesArray(){
        this.namesArray.push({"firstName": 'Charles', "lastName": 'Charleston'})
        this.namesArray.push({"firstName": 'Albert', "lastName": 'Alberterson'})
        this.namesArray.push({"firstName": 'Bertrand', "lastName": ''})
     }
}

The reason for placing it in the computed property, instead of the methods is that this makes the value reactive, if namesArray now gains another element, the whole list is properly rerendered once. Methods don’t do this correctly.
We create a ‘copy’ of the namesArray to not touch the data in the object itself, since that will also trigger a rerender.

In Vue you can now do:

<ul>
    <li v-for="(namesList, index) in sortedNames" :key="index">
        {{namesList.firstName}}
    </li>
</ul>

The reason it’s not sorting is because ‘string’-‘string’ = NaN in javascript, so I replaced it with localeCompare

1👍

Few issues here:-

  1. You should not modify this.namesArray inside computed as the computed property will re-evaluate when some of its reactive dependencies have changed. This might create side-effect as items might be inserted into this.namesArray multiple times.
  2. So, update this.namesArray inside created method
  3. and simply sort the array by firstName inside addNamesToArray computed property using localeCompare() method like:
new Vue({
  el: "#myApp",
  data() {
    return {
      namesArray: []
    }
  },
  created() {
    this.namesArray.push({"firstName": 'Charles',"lastName": 'Charleston'})
    this.namesArray.push({"firstName": 'Albert',"lastName": 'Alberterson'})
    this.namesArray.push({"firstName": 'Bertrand',"lastName": 'Doe'})
  },
  computed: {
    addNamesToArray() {
      return this.namesArray.sort((a, b) => a.firstName.localeCompare(b.firstName))
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="myApp">
  <ul>
    <li v-for="(namesList, index) in addNamesToArray" :key="index">
      {{namesList.firstName}}
    </li>
  </ul>
</div>

0👍

You could try something like this, because it’s computed it will update when this.namesArray updates.

computed: {
    sortedNamesArray() {
        return this.namesArray.sort((a,b) => a.firstName - b.firstName);
    }
}

Leave a comment