从 Vue 中的 v-for 列表中删除重复项

Removing duplicates from a v-for list in Vue

我正在尝试按类别对笔记列表进行排序。我在一个类别中有多个笔记,因此 v-for returns 列表中指定的笔记类别倍数。

我知道我应该使用计算的 属性 来过滤列表,但我已经尝试了下面的 sortedCategories,但似乎无法正常工作。

也许也相关,我目前正在使用 Vue2 过滤器按字母顺序对列表进行排序。在我得到没有重复的列表后,下一步是能够点击类别并拉出该特定类别中的所有笔记。

我的代码是:

<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>

<style scoped>
  .notebook {
    overflow-x: hidden;
    max-width: 20rem;
    width: 30rem;
    background: #d3d1d1;
  }

  .navbar {
    background-color: #000000;
    color: #dcdcdc;
    position: sticky;
    top: 0;
  }

  ul {
    list-style-type: none;
    padding: 0;
    margin: 0;
    height: 100%;
    position: relative;
  }

  li {
    padding: 1rem;
    font-size: 1.25rem;
    min-height: 1.5rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  li:hover {
    cursor: pointer;
    background-color: #a3a3a3;
  }

  .active {
    background-color: #0099ff;
  }

  .active:hover {
    background-color: #7cc1fa;
  }

  .new-page {
    background-color: #000000;
    color: white;
    bottom: 0;
    position: sticky;
    width: 100%;
    box-sizing: border-box;
  }

  .new-page:hover {
    background-color: #000000;
  }
</style>

computed 应该是导出的 Object 中的 top-level 键;现在它是 child 的 methods。尝试将其向上移动一级:

export default {
        name: 'Notebook',
        props: ['pages', 'activePage'],   
        mixins: [Vue2Filters.mixin],    

        computed: {
            sortedCategories() {
                return  this.pages.filter(function(page, position) {
                    return this.pages.indexOf(page.category)  == position; 
                });
            }
        }

        methods: {
          changePage (index) {
            this.$emit('change-page', index)
          },
        
          
          newPage () {
            this.$emit('new-page')
          },
         
        }
      }

如果您只想显示一个排序的唯一 category 字符串列表,您可以使用 vanilla JavaScript:

轻松做到这一点
  1. pages[] 上使用 Array.reduce()category 对数组条目进行分组,其中重复的类别将覆盖之前的类别(从而删除重复项)。
  2. 对结果 #1 使用 Object.values() 获取数组条目。
  3. 在结果 #2 上使用 Array.sort()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>