【问题标题】:How do I match the union of two arrays in a v-for loop如何在 v-for 循环中匹配两个数组的并集
【发布时间】:2021-05-24 07:06:42
【问题描述】:

我有两个数组:usersprojects。两者中的 ID 都是唯一的数字。一个项目可以有多个所有者,因此在projects 中,我有一组名为ownersId 的用户ID,它们链接到users 中用户的id,如下所示:

export const users = [{
    id: 1,
    givenName: 'Alexander',
    surname: 'Kelly',
    initials: 'AK'
}, {
    id: 2,
    givenName: 'Karen',
    surname: 'Jones',
    initials: 'KJ'
}, {
    id: 3,
    givenName: 'Casey',
    surname: 'Fields',
    initials: 'CF'
}, {
    id: 4,
    givenName: 'Sam',
    surname: 'Johns',
    initials: 'SJ'
}, {
    id: 5,
    givenName: 'Thomas',
    surname: 'Smith',
    initials: 'TS'
}, {
    id: 6,
    givenName: 'Jack',
    surname: 'Jenson',
    initials: 'JJ'
}];
export const projects = [{
    id: 1,
    name: 'Project 1',
    ownersId: [
        1,
        2,
        5,
        6,
    ]}, {
    id: 2,
    name: 'Project 2',
    ownersId: [
        1,
        3,
    ]}, {
    id: 3,
    name: 'Project 3',
    ownersId: [
        1,
        2,
        4,
        3, 
    ]}, {
    id: 4,
    name: 'Project 4',
    ownersId: [
        1,  
    ]}, {
}]

我想要做的是循环查看project 的详细信息,我已经使用v-for 成功完成了该操作。我坚持的是在循环中显示一个循环,该循环使用 ownersId 字段中的 ID 显示所有 users 名称。

<template>
    <div class="demo">
        <div 
            v-for="project in projects"  
            v-bind:key="project.id" 
        >
            <h4><strong>{{ project.name }}</strong></h4>
            <div v-if="project.ownersId" >
                Shared with {{ project.ownersId.length }} others
            </div>
            <div>
                <!-- Loop of the list of names from IDs goes here -->
            </div>
        </div>
    </div>
</template>

<script>
import { projects } from '../data/example';
import { users }  from '../data/example';

export default {
    name: "Demo",
    data() {
        return {
            projects,
            users,
        }
    }
}
</script>

【问题讨论】:

    标签: javascript arrays vue.js vuejs2 vue-component


    【解决方案1】:

    欢迎来到 SC。

    鉴于这是 2 个数组,我觉得最好的方法是简单地创建一个基于项目返回用户数据的方法,然后遍历该数据。

    methods:{
     getUserList(project){
      return project.ownersId.map(id=>
        users.find(user=>user.id===id)
       )
     }
    }
    

    然后像这样使用这个方法

    <div v-for="project in projects" :key="project.id">
    ...
      <!-- Loop of the list of names from IDs goes here -->
      <template v-for="user in getUserList(project)" :key="user.id"> 
        {{ user }}
      </template>
    ...
    </div>
    

    【讨论】:

      【解决方案2】:

      将您的用户数据数组转换为计算对象以便快速查找。然后将只有 1 次数据迭代,以创建对象。该对象也将被缓存,因为它是一个计算对象,因此重新渲染不会再次触发迭代。

      这可以防止大量多余的数组循环和查找,这对于较大数据集的性能可能很重要,尤其是在模板因任何原因重新渲染时。

      computed: {
        userData() {
          const userData = {};
          this.users.forEach(user => {
            userData[user.id] = user;
          });
          return userData;
        }
      }
      

      模板

      <div 
          v-for="project in projects"  
          v-bind:key="project.id" 
      >
          <h4><strong>{{ project.name }}</strong></h4>
          <div v-if="project.ownersId" >
              Shared with {{ project.ownersId.length }} others
          </div>
          <div>
              <div v-for="userId in project.ownersId" :key="userId">
                  {{ userData[userId] }}
              </div>
          </div>
      </div>
      

      这是demo

      【讨论】:

      • 感谢您的回答。第一次使用computed: 并且不知道它应该在语法中的哪个位置,最后确实弄清楚了。可能是一个愚蠢的问题,但为了性能,计算对象应该放在更大的项目中,在 component.vue 或 main.js 级别?
      • 不客气。回答您的后续问题:我会将计算结果与组件一起保留,或者这就是您可能会在 Vuex 中保留的那种状态。无论哪种方式,它都不会对性能产生太大影响。虽然离开组件并返回确实会导致第 1 次迭代再次发生,但每次访问只有 1 次迭代,即使有 100 个用户和 100 个项目也是如此。另一方面,使用数组查找 100 个项目,每个项目有 4 个用户,每次访问,每次渲染需要 400 次迭代。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-27
      • 2022-06-25
      • 1970-01-01
      • 2020-08-18
      • 2017-12-28
      • 2020-11-07
      相关资源
      最近更新 更多