在Vue.js中,前端控制通常指的是通过Vue的响应式系统、组件化、路由、状态管理等技术来实现对前端应用的控制和管理
一、前端路由控制基础
使用 vue-router
管理路由,通过路由守卫和动态添加路由实现权限控制。
1. 安装和配置
npm install vue-router@4
//路由实例
const router = createRouter({
history: createWebHashHistory(),
});
二、动态路由实现原理
根据用户权限动态生成路由表,通过 router.addRoute()
添加路由
1. 定义路由模板(静态+动态)
//基础路由
const baseRoutes = [
{
path: "/",
name: "login",
component: () => import("../views/login.vue"),
},
{
path: "/totalTwo",
component: () => import("../views/total/totalTwo.vue"),
children: [],
},
{
path: "/totalOne",
component: () => import("../views/total/totalOne.vue"),
children: [],
},
{
path: "/home",
name: "home",
component: () => import("../views/home.vue"),
meta: { title: "首页" },
},
];
//=============== 动态路由配置
const dynamicRoutes = [
{
path: "/about",
name: "about",
component: () => import("../views/aboutPage.vue"),
meta: { requiresAuth: true, permissions: ["2"] },
},
{
path: "/dashboard",
name: "Dashboard",
component: () => import("../views/Dashboard.vue"),
meta: { requiresAuth: true, permissions: ["1"] },
},
];
console.log(dynamicRoutes, "全部路由");
// 路由实例
const router = createRouter({
history: createWebHashHistory(),
routes: [...baseRoutes, ...dynamicRoutes], // 初始化时合并路由
});
2. 动态添加路由
// 递归过滤路由函数
function filterRoutes(routes) {
return routes
.map((route) => {
// 检查当前路由权限
const hasPermission = store.permissions?.some(perm =>
route.meta.permissions.includes(perm)
);
// 无权限直接返回null
if (!hasPermission) return null;
// 创建路由副本避免污染原始数据
const filteredRoute = { ...route };
// 递归处理子路由
if (filteredRoute.children) {
filteredRoute.children = filterRoutes(filteredRoute.children);
// 可选:如果子路由全被过滤且父路由不需要独立存在
// if (filteredRoute.children.length === 0 && !filteredRoute.component) {
// return null;
// }
}
return filteredRoute;
})
.filter(route => route !== null); // 过滤掉null项
}
// 获取过滤后的多维路由结构
const allowedRoutes = filterRoutes(dynamicRoutes);
// 添加路由的逻辑保持不变
allowedRoutes.forEach((route) => {
if (!router.hasRoute(route.name)) {
router.addRoute(route); // 保持原有嵌套结构直接添加
}
});
三、路由守卫实现权限控制
使用全局前置守卫验证权限
// router/index.js
router.beforeEach((to, from, next) => {
const isAuthenticated = localStorage.getItem('token')
// 需要登录但未登录
if (to.meta.requiresAuth && !isAuthenticated) {
next('/login')
}
// 已登录但访问/login
else if (to.path === '/login' && isAuthenticated) {
next('/dashboard')
}
// 检查路由权限
else if (to.meta.role && !userRoles.includes(to.meta.role)) {
next('/404') // 无权限页面
}
else {
next()
}
})
四、动态菜单生成
根据过滤后的路由生成导航菜单
<!-- 在侧边栏组件中 -->
<template>
<div v-for="route in accessibleRoutes" :key="route.path">
<router-link :to="route.path">{{ route.meta?.title }}</router-link>
<div v-if="route.children">
<!-- 递归处理子路由 -->
</div>
</div>
</template>
<script>
import { computed } from 'vue'
import { useRouter } from 'vue-router'
export default {
setup() {
const router = useRouter()
const accessibleRoutes = computed(() => {
return router.options.routes.filter(route =>
!route.meta?.hidden && hasPermission(route)
})
return { accessibleRoutes }
}
}
</script>