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

Posted

技术标签:

【中文标题】从 Vue 中的 v-for 列表中删除重复项【英文标题】:Removing duplicates from a v-for list in Vue 【发布时间】:2020-10-10 22:42:12 【问题描述】:

我正在尝试按类别对我的笔记列表进行排序。我在一个类别中有多个笔记,所以v-for 在列表中多次返回分配的笔记类别。

我知道我应该使用计算属性来过滤列表,但我已经尝试过下面的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>

【问题讨论】:

【参考方案1】:

如果您只想显示唯一的 category 字符串的排序列表,您可以使用 vanilla javascript 轻松做到这一点:

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

【讨论】:

【参考方案2】:

computed 应该是导出对象中的***键;现在它是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')
          ,
         
        
      

【讨论】:

感谢您的建议。我把它移了上去,仍然没有运气。根据我看过的一些计算属性示例,我觉得我的语法或方法是错误的。我已经看到一些使用 v-for 输出附近的计算属性的名称来获得正确的结果,但考虑到我在 page.category 上使用 orderBy 来获得正确的结果,我不确定如何做到这一点以 ABC 顺序输出的列表。同样,这是全新的,我什至可能不会接近。我将使用当前尝试更新代码。

以上是关于从 Vue 中的 v-for 列表中删除重复项的主要内容,如果未能解决你的问题,请参考以下文章

删除 v-for 指令中的列表项

Vuejs - 如何使用 v-for 获取数组中的所有唯一值(删除重复项)

从 Ocaml 中的列表列表中删除重复项?

使用 Python 删除对象列表中的重复项

从列表中删除重复项?

204vue之v-for的“就地复用”和“key使用”