首页 > 解决方案 > 具有多个条件的数组操作 – Vue.js / JavaScript

问题描述

在我的 Vue.js 应用程序中,我使用导航抽屉来显示用户可以访问的不同页面。页面也只有在管理员激活了相关模块时才可见。moduleID因此,为每个页面和子页面设置了唯一性。该列表由 填充filteredPages[]。该数组是仅显示用户有权访问的页面的结果。所有可用页面都存储在我的原始数据源pages[]中。

总结一下:只有当这两个条件都为时才会显示一个页面:

  1. activatedModules[]包含moduleID页面子项。
  2. userPermissions[]包含子项的permissions值(如果没有子项,则为页面)。

我的代码:

export default {
    data: () => ({
        pages: [
            {
                text: 'Team', moduleID: 'm1',
                children: [
                { text: 'Dashboard', route:'team/dashboard', permissions: 'p101', moduleID: 'm1-1' },
                ],
            },
            {
                text: 'Planner', moduleID: 'm2',
                children: [
                { text: 'Events', route:'/planner/events', permissions: 'p201', moduleID: 'm2-1' },
                { text: 'Calendar', route:'/planner/calendar', permissions: 'p202', moduleID: 'm2-2' },
                ],
            },
            {
                text: 'HR', moduleID: 'm3',
                children: [
                { text: 'Staff', route:'/hr/staff', permissions: 'p301', moduleID: 'm3-1' },
                { text: 'Config', route:'/hr/config', permissions: 'p302', moduleID: 'm3-2' },
                ],
            },
            {
                text: 'Admin', moduleID: 'm4',
                children: [
                { text: 'Users', route:'/admin/users', permissions: 'p401', moduleID: 'm4-1' },
                { text: 'Security', route:'/admin/security', permissions: 'p402', moduleID: 'm4-2' },
                ],
            },
            { text: 'Support', route:'/support', permissions: 'p50', moduleID: 'm5' },
        ],
        activatedModules: ['m1', 'm1-1', 'm3', 'm3-1', 'm3-2' 'm4', 'm4-1', 'm4-2', 'm5'],
        userPermissions: ['p101', 'p301', 'p302', 'p402', 'p50'],
        // This is the source for my navigation drawer:
        filteredPages: []
    }),
    computed: {
        filterArray() {
            // I tried to use filter() but how can I solve the rest?
            this.filteredPages = this.pages.filter(function(item) {
              for (var this.activatedModules in filter) {
                if /* I would assume that I have to write the condition here */
                return false;
              }
              return true;
            })
        }
    }
}

对于上面的代码,这应该是输出:

filteredPages: [
                {
                    text: 'Team', moduleID: 'm1',
                    children: [
                        { text: 'Dashboard', route:'team/dashboard', permissions: 'p', moduleID: 'm1-1' },
                    ],
                },
                // Notice that 'm2' is missing here because it is not in activatedModules[]
                {
                    text: 'HR', moduleID: 'm3',
                    children: [
                        { text: 'Staff', route:'/hr/staff', permissions: 'p301', moduleID: 'm3-1' },
                        { text: 'Config', route:'/hr/config', permissions: 'p302', moduleID: 'm3-2' },
                    ],
                },
                {
                    text: 'Admin', moduleID: 'm4',
                    children: [
                        // 'm4-1' is in activatedModules[] but the user doesn't have the permission 'p401' to view this
                        { text: 'Security', route:'/admin/security', permissions: 'p402', moduleID: 'm4-2' },
                    ],
                },
                { text: 'Support', route:'/support', permissions: 'p50', moduleID: 'm5' },
            ]

用户的权限存储在 Firebase Cloud Firestore 中,如下所示:

数据模型截图

你能帮忙过滤数组吗?

标签: javascriptarraysvue.js

解决方案


一些备注:

  • 你不应该使用functionfor 回调,就像你开始做的那样 for filter,因为这会让你失去正确的this价值。使用箭头函数。
  • filter不能自己完成这项工作,因为您还需要生成可能有更少子级的新对象。所以你应该首先map制作那些缩小的对象,然后filter

在不使用 Vue 的情况下,您可以运行以下代码片段,它只是将调用硬编码为filterArray

let app = {
    computed: {
        filterArray() {
            this.filteredPages = this.pages.map(item => {
                let children = (item.children || []).filter(child => 
                    this.activatedModules.includes(child.moduleID) &&
                    this.userPermissions.includes(child.permissions)
                );
                return (children.length || !item.children) 
                    && this.activatedModules.includes(item.moduleID)
                    && {...item, children};
            }).filter(Boolean);
        }
    },
    data: () => ({
        pages: [
            {
                text: 'Team', moduleID: 'm1',
                children: [
                { text: 'Dashboard', route:'team/dashboard', permissions: 'p101', moduleID: 'm1-1' },
                ],
            },
            {
                text: 'Planner', moduleID: 'm2',
                children: [
                { text: 'Events', route:'/planner/events', permissions: 'p201', moduleID: 'm2-1' },
                { text: 'Calendar', route:'/planner/calendar', permissions: 'p202', moduleID: 'm2-2' },
                ],
            },
            {
                text: 'HR', moduleID: 'm3',
                children: [
                { text: 'Staff', route:'/hr/staff', permissions: 'p301', moduleID: 'm3-1' },
                { text: 'Config', route:'/hr/config', permissions: 'p302', moduleID: 'm3-2' },
                ],
            },
            {
                text: 'Admin', moduleID: 'm4',
                children: [
                { text: 'Users', route:'/admin/users', permissions: 'p401', moduleID: 'm4-1' },
                { text: 'Security', route:'/admin/security', permissions: 'p402', moduleID: 'm4-2' },
                ],
            },
            { text: 'Support', route:'/support', permissions: 'p50', moduleID: 'm5' },
        ],
        activatedModules: ['m1', 'm1-1', 'm3', 'm3-1', 'm3-2', 'm4', 'm4-1', 'm4-2', 'm5'],
        userPermissions: ['p101', 'p301', 'p302', 'p402', 'p50'],
        filteredPages: []
    }),
};

// Demo, simulate Vue's call to computed.filterArray
let data = app.data();
app.computed.filterArray.call(data);
// Verify output:
console.log(data.filteredPages);


推荐阅读