user10991526
user10991526

Reputation: 135

Switching sorting function with VueJS

I'm making sorting function by Vue js

Ideal behaviour is like this,

I added switchng function on computed named sort.

I don't even know why ex1) works but ex2) doesn't

Please help if you know.

Thanks

new Vue({
  el: '#app',
  data: {
    asc: false,
    desc: false,
    list: [],
  },
  created: function () {
    axios.get('https://jsonplaceholder.typicode.com/users')
      .then(function (response) {
      this.list = response.data
    }.bind(this)).catch(function (e) {
      console.error(e)
    })
  },
  methods: {
  },

  computed: {
    sort: function() {
      if (this.asc) {            //ordered by asc
        this.desc = false        // NOT WORKING!!!
        console.log(`this.desc ${this.desc}`);
        return _.orderBy(this.list, 'name', 'asc')

      } else if (this.desc) {   //ordered by desc
        this.asc = false
        console.log(`this.asc ${this.asc}`);
        return _.orderBy(this.list, 'name', 'desc')
      }
    },
    sorted: function() {
      if (this.asc) {
        return this.sort

      } else if (this.desc) {
        return this.sort

      } else {
        return this.list
      }
    },


  }
})
span {font-weight: bold;}
.is-active {background: turquoise;}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>



<div id="app">
  <ul>
    <li v-for="item in sorted" :key="item.id">
      <span>ID:</span> {{item.id}} ,  <span>Name:</span> {{item.name}} ,  <span>Company:</span> {{item.company.name}}
    </li>
  </ul>

  <button :class="{'is-active': asc}"  @click="asc=!asc">asc by name</button>
  <button :class="{'is-active': desc}" @click="desc=!desc">desc by name</button>
</div>

Upvotes: 0

Views: 1779

Answers (1)

y_nk
y_nk

Reputation: 2275

Usually, computed shouldn't mutate data. If you want to do so, I'd suggest you make watchers instead.

You can notice that your application refreshes twice when togging those buttons by adding a console.log into the updated() lifecycle function of your component.

Change the computed part to:

sorted() {
  if (this.asc) {
    return _.orderBy(this.list, 'name', 'asc')
  } else if (this.desc) {
    return _.orderBy(this.list, 'name', 'desc')
  }

  return this.list
},

And add watchers instead:

watch: {
  asc(newVal) {
    if (this.desc && newVal)
      this.desc = false
  },

  desc(newVal) {
    if (this.asc && newVal)
      this.asc = false
  },
},

On the optimization side:

For most of the time you wrote function() you don't need it.

For the created() part, you can have a look at fat arrows to help reduce the complexity of your code.

axios.get('https://jsonplaceholder.typicode.com/users')
  .then(response => this.list = response.data)
  .catch(e => console.error(e))

The component methods can be written directly as functionName() {} rather than functionName: function() {} as a shorthand for clarity.

Also, you don't need the 2 separate computed ; one is enough for your case.

Upvotes: 2

Related Questions