VJSP Vue3 Framework Main Documentation
Project Overview
VJSP Vue3 Framework is an enterprise-level frontend solution for middle and back-office systems based on Vue 3.5 + TypeScript 5.7 + Element Plus. The framework provides a complete set of development tools and component libraries to help developers quickly build modern web applications.
Technology Stack Architecture
Based on the actual project configuration, the framework uses the following core technology stack:
- Frontend Framework: Vue 3.5.13 + Composition API
- Build Tool: Vite 6.0.7
- Type System: TypeScript 5.7.3
- UI Component Library: Element Plus 2.11.7
- State Management: Pinia 3.0.0 + Persistence Plugin
- Routing Management: Vue Router 4.5.0
- Internationalization: Vue I18n 11.0.1
- HTTP Client: Axios 1.12.0
Project Structure
The project adopts a modular architecture design with the following main directory structure:
src/
├── api/ # API Interface Layer
│ ├── login/ # Login Related APIs
│ ├── user/ # User Management APIs
│ └── system/ # System Management APIs
├── components/ # Component Layer
│ ├── SvgIcon/ # SVG Icon Component
│ └── dict/ # Dictionary Component
├── stores/ # State Management
│ ├── app.ts # Application State
│ ├── user.ts # User State
│ └── modules/ # Modular States
├── utils/ # Utility Functions
│ ├── cache.ts # Cache Management
│ ├── encryption.ts # Encryption Tools
│ └── tree.ts # Tree Data Processing
├── views/ # Page Components
│ ├── system/ # System Management Pages
│ └── dashboard/ # Dashboard Pages
└── main.ts # Application EntryCore Function Mechanisms
1. Application Startup Mechanism
The framework uses an asynchronous startup mechanism to ensure all dependencies are properly initialized:
// Startup process in src/main.ts
async function bootstrap() {
const app = createApp(App)
// 1. Register Element Plus Icons
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
// 2. Initialize Pinia State Management
app.use(createPinia())
// 3. Initialize Internationalization
await setupI18n(app)
// 4. Configure Element Plus
app.use(ElementPlus, {
locale: currentLocale.elLocale,
})
// 5. Set up Router (Wait for Dynamic Route Loading)
await setupRouter(app)
app.mount('#app')
}2. Permission Management Mechanism
The framework implements a role-based permission control system:
- Menu Permissions: Dynamic route filtering, only displaying authorized menus
- Button Permissions: Control button display through custom directives
- Data Permissions: Filter data access scope based on user roles
Permission verification is implemented through route guards and custom directives:
// Route Guard Permission Check
router.beforeEach(async (to, from, next) => {
// Check user login status
if (to.meta.requiresAuth && !isAuthenticated()) {
next('/login')
return
}
// Check route permissions
if (to.meta.permission && !hasPermission(to.meta.permission)) {
next('/403')
return
}
next()
})3. Internationalization Mechanism
The framework supports multi-language switching, implemented based on vue-i18n:
- Language Package Management: Organize language files by module
- Dynamic Switching: Support runtime language switching
- Component Integration: Element Plus components automatically adapt to current language
Language configuration is managed through independent plugin modules:
// Configuration in src/plugins/vueI18n
export async function setupI18n(app: App) {
const options = await createI18nOptions()
const i18n = createI18n(options)
app.use(i18n)
}4. State Management Mechanism
Uses Pinia for state management, supporting modular organization and persistence:
- Modular Design: Divide Store by functional modules
- Type Safety: Complete TypeScript type support
- Persistence: Key states automatically persist to local storage
State persistence is implemented through pinia-plugin-persistedstate:
// Store Configuration Example
const useUserStore = defineStore('user', {
state: () => ({
token: '',
userInfo: {},
permissions: [],
}),
persist: {
key: 'user-store',
storage: localStorage,
},
})5. Build Optimization Mechanism
Vite build tool provides the following optimization mechanisms:
- Dependency Pre-building: Pre-build third-party dependencies to improve loading speed
- Code Splitting: Automatically split vendor packages and business code
- Tree Shaking: Automatically remove unused code
- Compression Optimization: Automatically enable compression in production environment
Build configuration is managed through vite.config.ts file:
// Build Optimization Configuration
export default defineConfig({
build: {
// Code Splitting Configuration
rollupOptions: {
output: {
manualChunks: {
vue: ['vue'],
'element-plus': ['element-plus'],
},
},
},
},
})Product Module Development Example
1. Create Product Module Structure
Assuming development of Product module, create directory structure according to project unified specifications:
src/
├── api/ # API Interface Layer (Unified Management)
│ └── product/ # Product Related APIs
│ └── index.ts # Product API Service
├── types/ # Type Definitions (Unified Management)
│ └── api/ # API Related Types
│ └── product.ts # Product Related Type Definitions
├── locales/ # Internationalization Copy
│ └── module/ # Module Copy
│ └── product/ # Product Module Copy
│ └── en-US.ts
└── views/modules/product/ # Product Page Components
├── components/ # Product Related Components (If Needed)
│ ├── ProductForm.vue # Product Form Component
│ └── ProductTable.vue # Product Table Component
└── index.vue # Product Management Main Page2. Define Product Types
Create TypeScript type definitions for products in the unified type definition directory:
// src/types/api/product.ts
export interface Product {
id: number
name: string
price: number
description: string
category: string
status: 'active' | 'inactive'
createdAt: string
updatedAt: string
}
export interface ProductForm {
name: string
price: number
description?: string
category: string
}
export interface ProductFilters {
category?: string
status?: string
search?: string
page: number
pageSize: number
}
export interface ProductListResponse {
list: Product[]
total: number
}3. Implement Product API Service
Encapsulate product-related API interfaces in the unified API directory:
// src/api/product/index.ts
import request from '@/axios'
import type { Product, ProductForm, ProductFilters, ProductListResponse } from '@/types/api/product'
export class ProductApiService {
// Get Product List
static async getProducts(params: ProductFilters) {
return request.get<ProductListResponse>({
url: '/api/products',
params,
})
}
// Get Product Details
static async getProduct(id: number) {
return request.get<Product>({
url: `/api/products/${id}`,
})
}
// Create Product
static async createProduct(data: ProductForm) {
return request.post<Product>({
url: '/api/products',
data,
})
}
// Update Product
static async updateProduct(id: number, data: ProductForm) {
return request.put<Product>({
url: `/api/products/${id}`,
data,
})
}
// Delete Product
static async deleteProduct(id: number) {
return request.delete({
url: `/api/products/${id}`,
})
}
}
export default ProductApiService4. Create Product Internationalization Copy
Create copy for product module in the unified internationalization directory:
// src/locales/module/product/en-US.ts
export default {
product: {
title: 'Product Management',
list: 'Product List',
name: 'Product Name',
category: 'Product Category',
price: 'Price',
status: 'Status',
createdAt: 'Created At',
operation: 'Operation',
search: 'Search',
reset: 'Reset',
add: 'Add Product',
edit: 'Edit',
delete: 'Delete',
export: 'Export Data',
placeholder: {
name: 'Please enter product name',
category: 'Please select category',
},
statusText: {
active: 'Active',
inactive: 'Inactive',
},
message: {
loadFailed: 'Failed to load product list',
deleteSuccess: 'Delete successful',
deleteFailed: 'Delete failed',
exportSuccess: 'Export function under development',
exportFailed: 'Export failed',
confirmDelete:
'Are you sure you want to delete product "{name}"? This operation cannot be undone.',
},
categories: {
electronics: 'Electronics',
home: 'Home Goods',
clothing: 'Clothing & Accessories',
food: 'Food & Beverages',
},
},
}5. Create Product Management Page
Implement the main product management page with responsive design, supporting desktop and mobile, integrating internationalization, permission control, and data management functions:
Page Structure
The product management page uses a card-based layout with the following main areas:
- Filter Area - Supports filtering by product name, product code, category, status, etc.
- Data Display Area - Table view for desktop and card view for mobile
- Action Button Area - Add, batch delete, export and other functions
- Form Dialog - Product add/edit form
- Export Dialog - Data export configuration
Styles are integrated with src\styles\components\tables.less, no additional configuration needed unless special requirements
Core Features
- Responsive Design: Automatically adapts to desktop and mobile display
- Internationalization Support: Uses
t('product.xxx')syntax for multi-language copy - Permission Control: Controls button display through
v-permissiondirective - Data Management: Supports pagination, filtering, sorting, status switching
- Batch Operations: Supports batch delete and export
- Form Validation: Complete form validation rules
Main Component Structure
<template>
<div class="product-container query-container">
<!-- Filter Area -->
<el-card class="filter-container">
<!-- Mobile Expand/Collapse Function -->
<template #header v-if="isMobile">
<div class="filter-header">
<span>{{ t('common.filter') }}</span>
<el-button @click="filterExpanded = !filterExpanded">
{{ filterExpanded ? t('common.collapse') : t('common.expand') }}
</el-button>
</div>
</template>
<!-- Filter Form -->
<el-form :inline="!isMobile" :model="queryParams">
<el-row>
<el-col :xs="24" :sm="12" :md="8" :lg="8">
<el-form-item :label="t('product.productName')">
<el-input v-model="queryParams.productName" />
</el-form-item>
</el-col>
<!-- Other Filter Conditions -->
</el-row>
</el-form>
</el-card>
<!-- Data Display Area -->
<el-card class="table-container">
<template #header>
<div class="card-header">
<span v-if="!isMobile">{{ t('product.list') }}</span>
<div class="header-actions">
<el-button type="primary" @click="handleAdd">
{{ t('common.add') }}
</el-button>
<!-- Other Action Buttons -->
</div>
</div>
</template>
<!-- Desktop Table View -->
<div v-if="!isMobile" class="desktop-view">
<el-table :data="productList" v-loading="loading">
<!-- Table Column Definitions -->
</el-table>
</div>
<!-- Mobile Card View -->
<div v-else class="mobile-view">
<div v-loading="loading" class="mobile-cards-container">
<!-- Card List -->
</div>
</div>
<!-- Pagination and Loading Hints -->
</el-card>
<!-- Export Dialog -->
<el-dialog :title="t('product.exportTitle')" v-model="exportVisible">
<!-- Export Configuration Form -->
</el-dialog>
<!-- Product Edit Dialog -->
<el-dialog :title="dialog.title" v-model="dialog.visible">
<!-- Product Form -->
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { ElMessage, ElMessageBox } from 'element-plus'
import ProductFormDialog from './components/ProductFormDialog.vue'
import ProductApiService from '@/api/product'
import type { Product, ProductFilters } from '@/types/api/product'
const { t } = useI18n()
// Reactive Data
const loading = ref(false)
const productList = ref<Product[]>([])
// Search Form
const searchForm = reactive({
name: '',
category: '',
})
// Pagination Configuration
const pagination = reactive({
current: 1,
size: 10,
total: 0,
})
// Form Dialog Configuration
const formDialog = reactive({
visible: false,
data: null as Product | null,
mode: 'add' as 'add' | 'edit',
})
// Product Category Options (Based on Internationalization Copy)
const categories = computed(() => {
return Object.entries(t('product.categories', {}, { returnObjects: true })).map(
([value, label]) => ({
value,
label,
})
)
})
// Load Product List
const loadProductList = async () => {
loading.value = true
try {
const params: ProductFilters = {
...searchForm,
page: pagination.current,
pageSize: pagination.size,
}
const response = await ProductApiService.getProducts(params)
productList.value = response.data.list
pagination.total = response.data.total
} catch (error) {
ElMessage.error(t('product.message.loadFailed'))
console.error('Error loading product list:', error)
} finally {
loading.value = false
}
}
// Search Handling
const handleSearch = () => {
pagination.current = 1
loadProductList()
}
// Reset Search
const handleReset = () => {
Object.assign(searchForm, { name: '', category: '' })
handleSearch()
}
// Pagination Handling
const handleSizeChange = (size: number) => {
pagination.size = size
pagination.current = 1
loadProductList()
}
const handleCurrentChange = (current: number) => {
pagination.current = current
loadProductList()
}
// Add Product
const handleAdd = () => {
formDialog.mode = 'add'
formDialog.data = null
formDialog.visible = true
}
// Edit Product
const handleEdit = (product: Product) => {
formDialog.mode = 'edit'
formDialog.data = product
formDialog.visible = true
}
// Delete Product
const handleDelete = async (product: Product) => {
try {
await ElMessageBox.confirm(
t('product.message.confirmDelete', { name: product.name }),
t('product.delete'),
{
type: 'warning',
confirmButtonText: t('common.confirm'),
cancelButtonText: t('common.cancel'),
}
)
await ProductApiService.deleteProduct(product.id)
ElMessage.success(t('product.message.deleteSuccess'))
loadProductList()
} catch (error) {
if (error !== 'cancel') {
ElMessage.error(t('product.message.deleteFailed'))
console.error('Error deleting product:', error)
}
}
}
// Export Data
const handleExport = async () => {
try {
// Implement export logic
ElMessage.success(t('product.message.exportSuccess'))
} catch (error) {
ElMessage.error(t('product.message.exportFailed'))
console.error('Error exporting product data:', error)
}
}
// Form Submit Success Handling
const handleFormSuccess = () => {
formDialog.visible = false
loadProductList()
}
// Initialize Data on Page Load
onMounted(() => {
loadProductList()
})
</script>6. Configure Product Module Routes
Add product management module to route configuration:
Frontend Control Mode
// src/router/modules/product.ts
import type { RouteRecordRaw } from 'vue-router'
const productRoutes: RouteRecordRaw[] = [
{
path: '/product',
name: 'Product',
component: () => import('@/views/modules/product/index.vue'),
meta: {
title: 'product.title', // Use internationalization key
icon: 'shopping-bag',
requiresAuth: true,
permissions: ['product:view'],
},
children: [
{
path: 'list',
name: 'ProductList',
component: () => import('@/views/modules/product/index.vue'),
meta: {
title: 'product.list', // Use internationalization key
requiresAuth: true,
permissions: ['product:view'],
},
},
],
},
]
export default productRoutesThen import in main route file:
// src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router'
import productRoutes from './modules/product'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
// ... Other routes
...productRoutes,
// ... More routes
],
})
export default routerBackend Control Mode
Configure product module routes under the pre-built system management - menu management, including list, add, edit, delete and other operations.
Framework Core Advantages
1. Development Efficiency Improvement
- Component-based Development: Rich UI components based on Element Plus library
- Type Safety: Complete TypeScript support, reducing runtime errors
- Hot Reload: Vite development server supports real-time preview
- Code Standards: ESLint + Prettier ensure code quality
2. Performance Optimization
- Build Optimization: Vite provides fast cold start and hot updates
- Code Splitting: Automatically split vendor packages, optimize loading performance
- Cache Strategy: Multi-level cache mechanism improves application response speed
- Lazy Loading: Route and component lazy loading reduce initial bundle size
3. Enterprise-level Features
- Permission Management: Complete RBAC permission control system
- Internationalization: Multi-language support, adapting to global needs
- Data Dictionary: Unified data management mechanism
- Error Handling: Complete error capture and handling mechanism
4. Maintainability
- Modular Architecture: Clear directory structure and module division
- Type Definitions: Complete interface and type definitions
- Comprehensive Documentation: Detailed development documentation and examples
- Tool Integration: Deep integration with development tools
Summary
VJSP Vue3 Framework provides a complete enterprise-level frontend solution based on modern technology stacks and best practices. The framework's core advantages lie in its comprehensive permission management, internationalization support, performance optimization, and development efficiency improvement. Through the Product module development example, it demonstrates how to quickly build business function modules on the framework foundation.
The framework's design philosophy is "convention over configuration," reducing development complexity and improving development efficiency through reasonable default configurations and modular design. At the same time, the framework maintains good extensibility and can be customized and extended according to specific business needs.
