Reputation: 135
I'm making sorting function by Vue js
Ideal behaviour is like this,
Name
by ascending order when asc by name
button clicked -> done :)Name
by descending order when desc by name
button clicked -> done :)switch asc/desc function on/off by clicking the other button -> NOT WORKING!!
desc by name
button first, then, click asc by name
button -> doneasc by name
button first, then, click desc by name
button -> NOT WORKING!!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
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