Issue
After looking at [Vue.JS' documentation][1], we're provided with a method which, as an example, sorts by all even numbers. That's all good, but I'd like to sort an array by a name value inside an array - meaning I need to do a comparison. All the answers I've found have since been deprecated and the only solutions are using other modules than VueJS itself. Is this really not possible or am I just missing something obvious? [1]: https://v2.vuejs.org/v2/guide/list.html#Displaying-Filtered-Sorted-Results
Here's my example:
data() {
return {
namesArray: []
]
};
},
...
computed: {
addToNamesArray(){
this.namesArray.push({"firstName": 'Charles', "lastName": 'Charleston'})
this.namesArray.push({"firstName": 'Albert', "lastName": 'Alberterson'})
this.namesArray.push({"firstName": 'Bertrand', "lastName: ''"})
return this.namesArray
//(Obviously more complicated in reality, but let's keep it simple)
}
}
and in Vue:
<ul>
<li v-for="(namesList, index) in addNamesToArray" :key="index">
{{namesList.firstName}}
</li>
</ul>
Trying to sort within the computed property returns a "Unexpected side effect in computed property"-error, because one can't mutate inside a computed property. So my second try was making a method:
methods: {
sortNames(){
this.namesArray.sort((a,b) => a.firstName- b.firstName)
}
}
resulting in the new computed property:
computed: {
addToNamesArray(){
this.namesArray.push({"firstName": 'Charles', "lastName": 'Charleston'})
this.namesArray.push({"firstName": 'Albert', "lastName": 'Alberterson'})
this.namesArray.push({"firstName": 'Bertrand', "lastName: ''"})
this.sortNames()
return this.namesArray
}
}
but this does nothing(???)
I'd be really grateful if someone can explain to me why these solutions doesn't work and provide me with a one <3
Solution
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
Answered By - noahp78 Answer Checked By - Marie Seifert (PHPFixing Admin)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.