I have a select drop-down which displays the data either alphabetically or by relevance. It works okay but the issue I have is the data doesn't display when the page loads. It only displays after I have made a selection on the drop-down menu.
I tried adding variations of'this.sortItems();' this.sortatoz();and to mounted but this did not help.
What am I missing?
<select v-model="sortatoz" @change="sortItems">
<option disabled value="" selected>Select</option>
<option value="alphabetically">Alphabetically</option>
<option value="relevance">Relevance</option>
</select>
<div v-for="element in copiedList" :key="element">
<div>{{ element }}</div>
</div>
Computed:
sortItems() {
if (this.sortatoz === "alphabetically") {
this.copiedList = [...this.list].sort((a, b) => (a > b ? 1 : -1));
} else {
if (this.sortatoz === "relevance") {
this.copiedList = [...this.list];
}
}
},
return {
list: ["A", "C", "B"],
copiedList: [],
CodePudding user response:
Vuejs computed property are made to return
a property and then access this property from the dom (see this)
Here, you can return a new list from the computed property and show this list from the template.
new Vue({
el: "#app",
data: () => ({
list: ["A", "C", "B"],
copiedList: [],
sortatoz: "alphabeticallyAsc"
}),
computed: {
sortedItems() {
if (this.sortatoz === "alphabeticallyAsc") {
return [...this.list].sort((a, b) => (a > b ? 1 : -1));
} else if (this.sortatoz === "alphabeticallyDesc") {
return [...this.list].sort((a, b) => (a < b ? 1 : -1));
} else {
if (this.sortatoz === "relevance") {
return [...this.list];
}
}
},
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<select v-model="sortatoz">
<option disabled value="" selected>Select</option>
<option value="alphabeticallyAsc">Alphabetically ASC</option>
<option value="alphabeticallyDesc">Alphabetically DESC</option>
<option value="relevance">Relevance</option>
</select>
<div v-for="element in sortedItems" :key="element">
<div>{{ element }}</div>
</div>
</div>
Note : You could also have made another list and update this list onchange as you did
.
You can update the list in the mounted by setting the default value of the sort and triggering the sortItems
functions or more simply by making a copy of the array.
Here is an example of this implementation :
new Vue({
el: "#app",
data: () => ({
list: ["A", "C", "B"],
copiedList: [],
sortatoz: ""
}),
mounted(){
this.copiedList = [...this.list]
},
methods: {
sortItems() {
if (this.sortatoz === "alphabeticallyAsc") {
this.copiedList = [...this.list].sort((a, b) => (a > b ? 1 : -1));
} else if (this.sortatoz === "alphabeticallyDesc") {
this.copiedList = [...this.list].sort((a, b) => (a < b ? 1 : -1));
} else {
if (this.sortatoz === "relevance") {
this.copiedList = [...this.list];
}
}
},
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<select v-model="sortatoz" @change="sortItems">
<option disabled value="" selected>Select</option>
<option value="alphabeticallyAsc">Alphabetically ASC</option>
<option value="alphabeticallyDesc">Alphabetically DESC</option>
<option value="relevance">Relevance</option>
</select>
<div v-for="element in copiedList" :key="element">
<div>{{ element }}</div>
</div>
</div>