Routing Documentation - Route Configuration and Permission Control
Overview
This document details the routing configuration mechanism and permission control system of the VJSP Vue3 framework. The framework adopts a routing architecture based on Vue Router 4, combined with dynamic route generation and fine-grained permission control, providing a complete routing solution for enterprise-level applications.
Routing Architecture
Core Features
- Dynamic Route Generation: Supports both frontend-controlled and backend-controlled route generation modes
- Permission Integration: Deep integration of routing with permission system, achieving menu-level and button-level permission control
- Route Caching: Intelligent route caching mechanism to improve page switching performance
- Multi-level Route Support: Supports multi-level nested routes with automatic flattening
- Type Safety: Complete TypeScript type definition support
Technology Stack
- Vue Router 4: Core routing library
- Pinia State Management: Route state and permission state management
- Dynamic Import: Lazy loading of route components to optimize first-screen loading performance
- Permission Verification: Role-based access control (RBAC)
Route Configuration Mechanism
Routing Modes
The framework supports two route configuration modes:
- Frontend Control Mode: Route configuration is completely defined by the frontend, with the permission system responsible for filtering accessible routes
- Backend Control Mode: Route structure is returned by the backend, with the frontend dynamically generating routes based on backend data
Route Structure
Constant Routes
Constant routes are basic routes that must be loaded when the application starts, including:
- Login page
- 404 error page
- Redirect routes
- System basic pages (such as dashboard)
Dynamic Routes
Dynamic routes are generated dynamically based on user permissions, including:
- Business function module routes
- System management routes
- Personal center routes
Route Lazy Loading
The framework uses dynamic imports to implement lazy loading of route components, ensuring component loading safety through the createSafeDynamicImport function:
- Components loaded on demand to reduce initial bundle size
- Error boundary handling to prevent loading failures from affecting the application
- Support for component preloading to enhance user experience
Permission Control Mechanism
Permission Levels
The framework implements three-level permission control:
- Route-level Permission: Controls whether users can access specific pages
- Menu-level Permission: Controls the display of sidebar menus
- Button-level Permission: Controls the display of operation buttons within pages
Permission Verification Process
1. Route Guard Verification
Route guards execute permission verification during each route navigation:
- Check user login status
- Verify user permission information
- Generate accessible dynamic routes
- Add routes to the router instance
2. Permission Check Functions
The framework provides various permission check functions:
hasPermission: Check if specific permission is grantedhasAnyPermission: Check if any of the specified permissions are grantedhasAllPermissions: Check if all specified permissions are granted
3. Permission Directive
Button-level permission control is implemented through the v-permission directive, supporting various usage patterns and strict permission modes:
Basic Usage
<!-- Single permission check -->
<el-button v-permission="'system:user:add'">Add User</el-button>
<el-button v-permission="'system:user:edit'">Edit User</el-button>
<!-- Multiple permission check (satisfy any one permission) -->
<el-button v-permission="['system:user:add', 'system:user:edit']">
Add or Edit User
</el-button>Strict Permission Mode
Strict permission mode is implemented through modifiers, completely removing DOM elements when users lack permissions:
<!-- Strict mode: Remove element when no permission -->
<el-button v-permission.strict="'system:user:delete'">Delete User</el-button>
<!-- Strict mode with multiple permissions -->
<el-button v-permission.strict="['system:user:export', 'system:user:import']">
Data Import/Export
</el-button>Permission Directive Features
- Default Behavior: Disable elements when no permission (reduced opacity, non-clickable)
- Strict Mode: Use
.strictmodifier to completely remove elements when no permission - Dynamic Updates: Automatically update element state when permissions change
- Multiple Permission Checks: Support single permission or permission array (satisfy any permission)
Dynamic Route Generation
Frontend Control Mode
In frontend control mode, the route generation process is as follows:
- Get user permission list
- Filter predefined route configurations
- Generate accessible route tree
- Add to router instance
Backend Control Mode
In backend control mode, the route generation process is as follows:
- Get menu data from backend
- Convert menu data to route configuration
- Verify route component path validity
- Generate and add dynamic routes
Route Utility Functions
Route Generation Tools
The framework provides generateRoutesByFrontEnd and generateRoutesByServer functions to handle route generation for frontend and backend control modes respectively.
Route Processing Tools
pathResolve: Path resolution and normalizationflatMultiLevelRoutes: Multi-level route flatteningisValidRoute: Route configuration validation
Permission Check Tools
filterAccessibleRoutes: Filter accessible routesfindRouteByPath: Find route by pathfindRouteByName: Find route by name
Business Module Development Guide (Product Module)
1. Create Route Configuration
Create product.ts route configuration file in src/router/modules/ directory:
import type { AppRouteRecordRaw } from '@/router/types'
const ProductRoute: AppRouteRecordRaw = {
path: '/product',
name: 'Product',
component: () => import('@/layout/index.vue'),
meta: {
title: 'Product Management',
icon: 'product',
permission: ['product:view'],
},
children: [
{
path: 'list',
name: 'ProductList',
component: () => import('@/views/modules/product/list.vue'),
meta: {
title: 'Product List',
permission: ['product:list'],
},
},
{
path: 'add',
name: 'ProductAdd',
component: () => import('@/views/modules/product/add.vue'),
meta: {
title: 'Add Product',
permission: ['product:add'],
hidden: true,
},
},
{
path: 'edit/:id',
name: 'ProductEdit',
component: () => import('@/views/modules/product/edit.vue'),
meta: {
title: 'Edit Product',
permission: ['product:edit'],
hidden: true,
},
},
],
}
export default ProductRoute2. Register Route Module
Import and register product route module in src/router/index.ts:
import ProductRoute from './modules/product'
// Add to dynamic route configuration
const asyncRoutes: AppRouteRecordRaw[] = [
// ... other routes
ProductRoute,
]3. Create View Components
Create corresponding Vue component files:
src/views/modules/product/list.vue
<template>
<div class="product-list">
<SearchForm :fields="searchFields" @search="handleSearch" />
<DataTable
:columns="tableColumns"
:data="productList"
:loading="loading"
@refresh="loadProductList"
>
<template #action="{ row }">
<el-button v-permission="'product:edit'" @click="handleEdit(row)"> Edit </el-button>
<el-button v-permission="'product:delete'" @click="handleDelete(row)"> Delete </el-button>
</template>
</DataTable>
<el-button v-permission="'product:add'" type="primary" @click="handleAdd">
Add Product
</el-button>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useProductApi } from '@/api/modules/product'
const router = useRouter()
const productList = ref([])
const loading = ref(false)
const searchFields = [
{ label: 'Product Name', prop: 'productName', type: 'input' },
{ label: 'Product Code', prop: 'productCode', type: 'input' },
]
const tableColumns = [
{ label: 'Product Name', prop: 'productName' },
{ label: 'Product Code', prop: 'productCode' },
{ label: 'Price', prop: 'price' },
{ label: 'Status', prop: 'status' },
]
const loadProductList = async (params = {}) => {
loading.value = true
try {
const response = await useProductApi().getList(params)
productList.value = response.data.list
} finally {
loading.value = false
}
}
const handleAdd = () => {
router.push({ name: 'ProductAdd' })
}
const handleEdit = row => {
router.push({ name: 'ProductEdit', params: { id: row.id } })
}
const handleDelete = async row => {
// Delete confirmation and operation
}
onMounted(() => {
loadProductList()
})
</script>4. Permission Configuration
Configure permission identifiers for product module in permission management system:
product:view: View product moduleproduct:list: View product listproduct:add: Add productproduct:edit: Edit productproduct:delete: Delete product
Route Caching Mechanism
Route State Management
The framework uses Pinia to manage route state, including:
- Currently active route
- Tab route list
- Sidebar menu state
- Route cache identifiers
Component Caching
Route component caching is implemented through Vue Router's <keep-alive> and component name attribute:
- Intelligent cache management to avoid memory leaks
- Support for maximum cache count limits
- Manual cache clearing functionality
Route Persistence
Route state is automatically persisted to localStorage, ensuring:
- Route state is maintained after page refresh
- Tab state recovery
- Sidebar expansion state memory
Error Handling
Route Error Handling
The framework implements complete route error handling mechanism:
- 404 page handling
- Insufficient permission page
- Route loading failure handling
- Network error retry mechanism
Fallback Solution
When dynamic route loading fails, the framework provides fallback solutions:
- Use static routes as backup
- Display friendly error messages
- Provide retry mechanism
Best Practices
Route Naming Convention
- Use camelCase for route naming
- Keep route names consistent with component names
- Use meaningful path structures
Permission Configuration Suggestions
- Use modular naming for permission identifiers
- Maintain appropriate permission granularity
- Regularly clean up unused permissions
Performance Optimization
- Use route lazy loading appropriately
- Avoid excessive route nesting
- Regularly check route configurations
Common Questions
Q: How to add new business module routes?
A: Create route configuration file in src/router/modules/ directory and import/register in main route file.
Q: How to control button-level permissions?
A: Use v-permission directive with corresponding permission identifier.
Q: Route caching not working, what to do?
A: Ensure components have correct name attribute set and check meta.keepAlive setting in route configuration.
Q: How to implement dynamic menus?
A: Use backend control mode, get menu data from backend and convert to route configuration.
