当前位置: 首页 > 知识库问答 >
问题:

Vue路由器-如何根据用户角色在同一路由路径上加载多个组件?

商畅
2023-03-14

我有应用程序,用户可以登录在不同的角色,例如。对于每个用户,我想在相同的路径上显示仪表板页面,例如。http://localhost:8080/dashboard然而,每个用户将在不同的vue组件中定义不同的仪表板,例如。SellerDashboardBuyerDashboardAdminDashboard.

所以基本上,当用户打开http://localhost:8080/dashboardvue应用程序应根据用户角色(我存储在vuex中)加载不同的组件。类似地,我希望其他路线也有这个。例如,当用户转到配置文件页面http://localhost:8080/profile根据登录用户的不同,应用程序应显示不同的配置文件组件。

因此,我希望所有用户角色都有相同的路由,而不是每个用户角色都有不同的路由,例如,我不希望用户角色包含在url中,如下所示:http://localhost:8080/admin/profilehttp://localhost:8080/seller/profile等。。。

如何使用vue路由器实现此方案?

我尝试在输入前使用子路由和每个路由保护的组合来解析基于用户角色的路由。下面是一个代码示例:

在路由器中。js:

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import store from '@/store'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'home',
    component: Home,

    beforeEnter: (to, from, next) => {
      next({ name: store.state.userRole })
    },

    children: [
      {
        path: '',
        name: 'admin',
        component: () => import('@/components/Admin/AdminDashboard')
      },
      {
        path: '',
        name: 'seller',
        component: () => import('@/components/Seller/SellerDashboard')
      },
      {
        path: '',
        name: 'buyer',
        component: () => import('@/components/Buyer/BuyerDashboard')
      }
    ]
  },
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router

在商店里。js:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    userRole: 'seller' // can also be 'buyer' or 'admin'
  }
})

应用程序。vue包含顶级路由的父路由器视图,例如将/映射到组件和/about映射到about组件:

<template>
  <router-view/>
</template>

<script>
export default {
  name: 'App',
}
</script>

还有家。vue包含嵌套的路由器视图,用于不同用户基于角色的组件:

<template>
  <div class="home fill-height" style="background: #ddd;">
    <h1>Home.vue</h1>
    <!-- nested router-view where user specific component should be rendered -->
    <router-view style="background: #eee" />
  </div>
</template>

<script>
export default {
  name: 'home'
}
</script>

但是它不起作用,因为当我调用Next({name:store.state.userRole})时,浏览器控制台中的最大调用堆栈大小超过了异常。例外情况是:

vue-router.esm.js?8c4f:2079 RangeError: Maximum call stack size exceeded
    at VueRouter.match (vue-router.esm.js?8c4f:2689)
    at HTML5History.transitionTo (vue-router.esm.js?8c4f:2033)
    at HTML5History.push (vue-router.esm.js?8c4f:2365)
    at eval (vue-router.esm.js?8c4f:2135)
    at beforeEnter (index.js?a18c:41)
    at iterator (vue-router.esm.js?8c4f:2120)
    at step (vue-router.esm.js?8c4f:1846)
    at runQueue (vue-router.esm.js?8c4f:1854)
    at HTML5History.confirmTransition (vue-router.esm.js?8c4f:2147)
    at HTML5History.transitionTo (vue-router.esm.js?8c4f:2034)

因此什么也没有呈现。

我有办法解决这个问题吗?


共有3个答案

子车修平
2023-03-14

一种方法是使用动态组件。您可以有一个子路由,其组件也是非特定的(例如DashboardComponent):

router.js

const routes = [
  {
    path: '/',
    name: 'home',
    children: [
      {
        path: '',
        name: 'dashboard',
        component: () => import('@/components/Dashboard')
      }
    ]
  }
]

组件/仪表板。vue

<template>
  <!-- wherever your component goes in the layout -->
  <component :is="dashboardComponent"></component>
</template>

<script>
import AdminDashboard from '@/components/Admin/AdminDashboard'
import SellerDashboard from '@/components/Seller/SellerDashboard'
import BuyerDashboard from '@/components/Buyer/BuyerDashboard'

const RoleDashboardMapping = {
  admin: AdminDashboard,
  seller: SellerDashboard,
  buyer: BuyerDashboard
}

export default {
  data () {
    return {
      dashboardComponent: RoleDashboardMapping[this.$store.state.userRole]
    }
  }
}
</script>
闽念
2023-03-14

这样的代码仅检索给定角色的组件代码:

import Vue from "vue";
import VueRouter from "vue-router";
import Home from "../views/Home.vue";
import store from "../store";

Vue.use(VueRouter);

const routes = [
  {
    path: "/",
    name: "home",
    component: () => {
      switch (store.state.userRole) {
        case "admin":
          return import("../components/AdminDashboard");
        case "buyer":
          return import("../components/BuyerDashboard");
        case "seller":
          return import("../components/SellerDashboard");
        default:
          return Home;
      }
    }
  }
];

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes
});

export default router;
施玉宸
2023-03-14

您可能希望尝试以下解决方案:

<template>
  <component :is="compName">
</template>
data: () {
 return {
      role: 'seller' //insert role here - maybe on `created()` or wherever
 }
},
components: {
 seller: () => import('/components/seller'),
 admin: () => import('/components/admin'),
 buyer: () => import('/components/buyer'),
}

或者,如果您更喜欢整洁一点(相同的结果):

<template>
  <component :is="loadComp">
</template>
data: () => ({compName: 'seller'}),
computed: {
 loadComp () {
  const compName = this.compName
  return () => import(`/components/${compName}`)
 }
}

这将使您能够使用动态组件,而无需预先导入所有CMP,但每次只使用所需的一个。

 类似资料:
  • 我希望使用相同的路由路径,根据用户角色为我的用户加载稍微不同的视图。 以前,我已经加载了基于当前域的不同路由: 这种方法只依赖于子域,子域在创建时可用,因此所有内容都可以是同步的。我必须对用户进行身份验证,根据其角色加载正确的路由,然后导出路由器以初始化vue应用程序。 理想情况下,我可以加载基于用户角色的,,,其中可以包含角色的所有路由定义。 我正在使用Feathers-vuex,但我似乎不能等

  • 我有一个带有路由器插座的根应用程序组件,并且路由是从家庭模块路由加载的,该路由在其子路由中使用延迟加载和 loadchildren。家庭组件中有一个路由器插座,在家庭的所有子模块中也有延迟加载的路由器插座。路由工作正常,但子路由也加载到根路由器出口中。例如:- 组件“testCreateComponent”正在加载localhost:4200 / test/create和localhost:420

  • 我有几个路线,每个路线装载3个组件。所有管线上的两个组件都相同。当我在这些路由之间移动时,我希望传递新数据,在组件的某个初始化事件上,我希望填充该组件的数据,以便它反映在UI上。我还想重新触发正在加载的组件的引导动画。我该怎么做呢。因为现在,我不知道在组件的生命周期中,我将在哪里获取数据,并使用这些新数据重新提交组件。具体来说,在myapps/1和/newapp/I中有一个主视图组件和一个侧栏组件

  • 我有一个小难题来解决这个问题。 我有一个用户和一个管理员角色。 用户应该能够列出除管理员以外的所有用户。管理员可以列出所有用户。 我想到的第一个解决方案是检查控制器级别的角色: 但是我更想做的是在路线层面上,保持控制器更干净,但不知何故它确实起作用了。它只列出用户,即使我作为管理员登录。 有什么建议吗?谢谢!

  • 问题内容: 是否可以基于路由组动态加载控制器,js文件和模板?伪代码不起作用: 我已经看到了很多这样的问题,但是没有一个问题基于路由组加载js文件/控制器。 问题答案: 我设法解决了受@ calebboyd,http : //ify.io/lazy-loading-in-angularjs/ 和http://weblogs.asp.net/dwahlin/archive/2013/05/22/dy