I'm trying to sort my list of notes by category. I have multiple notes in a single category, so v-for
returns the assigned note category multiples times in the list.
I understand that I should use a computed property to filter the list, but I've experimented with the one below, sortedCategories
, and can't seem to get it working.
Perhaps also relevant, I'm using Vue2 filters to sort the list alphabetically currently. After I get the list working without duplicates the next step is to be able click on the category and pull up all the notes in that particular category.
My code is:
<template>
<div class="notebook">
<nav class="navbar" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
</div>
</nav>
<ul>
<!--
<li v-for="(page, index) of pages" class="page" v-bind:class="{ 'active': index === activePage }" @click="changePage(index)" v-bind:key="index">
<div>{{page.category}}</div>
</li>
-->
<li v-for="(page, index) of orderBy(pages, 'category')" class="page"
v-bind:class="{ 'active': index === activePage }" v-bind:key="index">
<div>{{ page.category }}</div>
</li>
<li class="new-page">Add Page +</li>
</ul>
</div>
</template>
<script>
import Vue from 'vue'
import Vue2Filters from 'vue2-filters'
Vue.use(Vue2Filters)
export default {
name: 'Notebook',
props: ['pages', 'activePage'],
mixins: [Vue2Filters.mixin],
computed: {
sortedCategories() {
return this.categories.filter(function (category, position) {
return this.pages.indexOf(category) == position;
});
}
},
methods: {
changePage(index) {
this.$emit('change-page', index)
},
newPage() {
this.$emit('new-page')
},
}
}
</script>
If you just want to display a sorted list of unique category
strings, you could easily do this with vanilla JavaScript:
Array.reduce()
on pages[]
to group the array entries by category
, where duplicate categories would overwrite the previous ones (thereby removing duplicates).Object.values()
on result #1 to get the array entries.Array.sort()
on result #2 to sort the array by category
.new Vue({
el: '#app',
data: () => ({
pages: [
{ id: 1, category: 'Technology' },
{ id: 2, category: 'Sports' },
{ id: 3, category: 'Business' },
{ id: 4, category: 'Health' },
{ id: 5, category: 'Technology' },
{ id: 6, category: 'Health' },
{ id: 7, category: 'Technology' },
]
}),
computed: {
sortedCategories() {
const cats = this.pages.reduce((p,c) => {
p[c.category] = c
return p
}, {})
return Object.values(cats).sort((a,b) => a.category.localeCompare(b.category))
}
}
})
<script src="https://unpkg.com/vue@2.6.12"></script>
<div id="app">
<ul>
<li v-for="cat of sortedCategories" :key="cat.id">
<div>{{ cat.category }}</div>
</li>
</ul>
</div>