VUE路由器-如何根据用户角色将多个组件加载到同一路由路径上?
我有应用程序,用户可以登录在不同的角色,例如。seller
、buyer
和admin
。
对于每个用户,我想在相同的路径上显示仪表板页面,例如。http://localhost:8080/dashboard
但是,每个用户将在不同的VUE组件中定义不同的仪表板,例如,SellerDashboard
、BuyerDashboard
和AdminDashboard
。
http://localhost:8080/dashboard
时,VUE应用程序应该根据用户角色加载不同的组件(我将其存储在VUEX中)。同样地,我想把这张票换成其他路线的票。例如,当用户转到配置文件页面http://localhost:8080/profile
时,应用程序应根据登录的用户显示不同的配置文件组件。
所以我希望所有用户角色都有相同的路由,而不是每个用户角色都有不同的路由,例如。我不希望用户角色包含在URL中,如下所示:http://localhost:8080/admin/profile
和http://localhost:8080/seller/profile
等.
如何使用VUE路由器实施此方案?
我尝试使用子路由和每路由防护的组合beforeEnter
来解析为基于用户角色的路由。以下是其中的一个代码示例:
在router.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
在store.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'
}
})
App.vue包含顶级路由的父路由视图,例如。将/
映射到Home
组件和/about
映射到About
组件:
<template>
<router-view/>
</template>
<script>
export default {
name: 'App',
}
</script>
和Home.vue包含不同用户基于角色的组件的嵌套router-view
:
<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>
但它不起作用,因为我在beforeEnter
中调用next({ name: store.state.userRole })
时,在浏览器控制台得到Maximum call stack size exceeded
异常。例外情况是:
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)
,因此不会呈现任何内容。
有没有办法可以解决这个问题?
解决方案
您可能需要尝试解决此解决方案:
<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,而只需每次使用所需的一个。
相关文章