如何解决多条件数组操作 – Vue.js / JavaScript
在我的 Vue.js 应用程序中,我使用导航抽屉来显示用户可以访问的不同页面。页面也只有在管理员激活相关模块时才可见。因此,为每个页面和子页面设置了唯一的 moduleID
。该列表由 filteredPages[]
填充。此数组是仅显示用户有权访问的页面的结果。所有可用页面都存储在我的原始数据源 pages[]
中。
我的代码:
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',children: [
{ text: 'Dashboard',permissions: 'p',// Notice that 'm2' is missing here because it is not in activatedModules[]
{
text: 'HR',children: [
{ text: 'Staff',{
text: 'Admin',children: [
// 'm4-1' is in activatedModules[] but the user doesn't have the permission 'p401' to view this
{ text: 'Security',]
用户的权限存储在 Firebase Cloud Firestore 中,如下所示:
你能帮忙过滤数组吗?
解决方法
在下面的代码片段中,我首先使用过滤器按 activatedModules
过滤,然后使用 forEach
过滤每个对象 children
属性按 userPermissions
,我认为您可以在你的 vue 组件中实现这一点或了解如何解决这个问题(希望这会有所帮助):
const pages = [{
text: 'Team',moduleID: 'm1',children: [{
text: 'Dashboard',route: 'team/dashboard',permissions: 'p1382',moduleID: 'm1-1'
},],},{
text: 'Planner',moduleID: 'm2',children: [{
text: 'Events',route: '/planner/events',permissions: 'p47289',moduleID: 'm2-1'
},{
text: 'Calendar',route: '/planner/calendar',permissions: 'p283',moduleID: 'm2-2'
},{
text: 'HR',moduleID: 'm3',children: [{
text: 'Staff',route: '/hr/staff',permissions: 'p34729',moduleID: 'm3-1'
},{
text: 'Config',route: '/hr/config',permissions: 'p382',moduleID: 'm3-2'
},{
text: 'Admin',moduleID: 'm4',children: [{
text: 'Users',route: '/admin/users',permissions: 'p3z4',moduleID: 'm4-1'
},{
text: 'Security',route: '/admin/security',permissions: 'p2u3',moduleID: 'm4-2'
},{
text: 'Support',route: '/support',permissions: 'p332j',moduleID: 'm5'
},];
const activatedModules = ['m1','m3','m4','m5'];
const userPermissions = ['m1-1','m3-1','m3-2','m4-2'];
// This is the source for my navigation drawer:
let filteredPages = null;
filteredPages = pages.filter(x => activatedModules.includes(x.moduleID));
filteredPages.forEach(x => {
if (x.children)
x.children = x.children.filter(y => userPermissions.includes(y.moduleID));
});
console.log(filteredPages);
一些说明:
- 您不应像开始为
function
那样使用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',children: [
{ text: 'Dashboard',route:'team/dashboard',permissions: 'p101',moduleID: 'm1-1' },{
text: 'Planner',children: [
{ text: 'Events',route:'/planner/events',permissions: 'p201',moduleID: 'm2-1' },{ text: 'Calendar',route:'/planner/calendar',permissions: 'p202',moduleID: 'm2-2' },{
text: 'HR',children: [
{ text: 'Staff',route:'/hr/staff',permissions: 'p301',moduleID: 'm3-1' },{ text: 'Config',route:'/hr/config',permissions: 'p302',moduleID: 'm3-2' },{
text: 'Admin',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','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);
应该这样做:
computed: {
filteredPages() {
return this.pages.map(page => ({
...page,children: page.children
// when children is truthy
? page.children.filter(
// filter out those not in `userPermissions`
child => this.userPermissions.includes(child.permissions)
// and those not in `activatedModules`
&& this.activatedModules.includes(child.moduleID)
)
: page.children
})).filter(
// only keep page if in `activatedModules` and...
page => (this.activatedModules.includes(page.moduleID)) &&
// if children is truthy and has length or...
(page.children?.length || (
// if children is falsy and page.permissions in userPermissions
!page.children && this.userPermissions.includes(page.permissions)
))
);
}
}
看看它是否有效:
Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
el: '#app',data: () => ({
pages: [
{
text: 'Team',children: [
{ text: 'Dashboard',moduleID: 'm1-1' }
],{
text: 'Planner',children: [
{ text: 'Events',{
text: 'HR',children: [
{ text: 'Staff',{
text: 'Admin',children: [
{ text: 'Users',moduleID: 'm5' }
],'p50']
}),computed: {
filteredPages() {
return this.pages.map(page => ({
...page,children: page.children
? page.children.filter(
child => this.userPermissions.includes(child.permissions)
&& this.activatedModules.includes(child.moduleID)
)
: page.children
})).filter(
page => (this.activatedModules.includes(page.moduleID))
&& (page.children?.length || (
!page.children && this.userPermissions.includes(page.permissions)
))
);
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<pre v-html="filteredPages" />
</div>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。