0

I have a basic application (As I am a complete beginner) in Electron + VueJS 2.X and I am looking to have a sorting function for v-for list. I have got it semi working in that I can sort but I would like to sort in reverse if a second click is applied. I am not sure the best way to go about this and maybe my current path I am heading down needs refinement. Please let me know how I can achieve this.

I was using 'selectedCategory' to track the current category and if it came up twice would run return this.items.reverse() but I couldn't get it to work.

I have cleaned up the code to help readability.

export default {
  name: 'home-page',
  data() {
    return {
      selectedCategory: null,
      items: [{
          id: 1,
          name: 'Person 1',
          leave: 123.45
        },
        {
          id: 2,
          name: 'John Smith',
          leave: 13.45
        },
        {
          id: 3,
          name: 'Bill Smith',
          leave: 23.45
        },
        {
          id: 4,
          name: 'John Doe',
          leave: 133.53
        }
      ]
    }
  },
  methods: {
    sortedByName: function() {
      function compare(a, b) {
        if (a.name < b.name) {
          return -1
        }
        if (a.name > b.name) {
          return 1
        }
        return 0
      }
      this.selectedCategory = 'name'
      return this.items.sort(compare)
    },
    sortedByNumber: function() {
      // Same as above but a.leave and b.leave
    },
    sortedById: function() {
      // Same as above but a.id and b.id
    }
  }
}
<template>
       <a v-on:click="sortedById()">ID</a>
       <a v-on:click="sortedByName()">User</a>
       <a v-on:click="sortedByNumber()">Leave Owing</a>
                  
       <div id="page_list">
          <div class="user_row" v-for="item in items">
             <div class="user_status">{{ item.id }}</div>
             <div class="username">{{ item.name }}</div>
             <div class="leave_owing">{{ item.leave }}</div>
           </div>
       </div>
</template>

Thanks

1 Answer 1

2

you can use computed

var app = new Vue({
  el: '#app',
  computed: {
    sortedData () {
      if(!this.sort.field){
        return this.items
      }

      return this.items.concat().sort((a,b)=>{
        if(this.sort.desc){
          return a[this.sort.field] > b[this.sort.field] ? -1:1        
        }else{
          return a[this.sort.field] > b[this.sort.field] ? 1:-1                  
        }
      })
    }
  },
  data () {
    return {
      sort: {
        field: '',
        desc: true        
      },
      items: [
        { id: 1, name: 'Person 1', leave: 123.45 },
        { id: 2, name: 'John Smith', leave: 13.45 },
        { id: 3, name: 'Bill Smith', leave: 23.45 },
        { id: 4, name: 'John Doe', leave: 133.53 }
      ]
    }
  },
  methods: {
    doSort (field) {
      if(field == this.sort.field){
        this.sort.desc = !this.sort.desc
      }else{
        this.sort.field = field;
        this.sort.desc = true;
      }
    }
  }
})
  .user_row{
    display:flex;
  }
  .user_row>div{
    flex:1;
    text-align: center;
  }
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<div id="app">
   <a v-on:click="doSort('id')" href="javascript:">ID<span v-if="sort.field=='id'">({{sort.desc?'desc':'asc'}})</span></a>
   <a v-on:click="doSort('name')" href="javascript:">User<span v-if="sort.field=='name'">({{sort.desc?'desc':'asc'}})</span></a>
   <a v-on:click="doSort('leave')" href="javascript:">Leave Owing<span v-if="sort.field=='leave'">({{sort.desc?'desc':'asc'}})</span></a>

   <div id="page_list">
      <div class="user_row" v-for="item in sortedData">
         <div class="user_status">{{ item.id }}</div>
         <div class="username">{{ item.name }}</div>
         <div class="leave_owing">{{ item.leave }}</div>
       </div>
   </div>
</div>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.