Skip to content

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:

shell
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 Entry

Core Function Mechanisms

1. Application Startup Mechanism

The framework uses an asynchronous startup mechanism to ensure all dependencies are properly initialized:

typescript
// 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:

typescript
// 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:

typescript
// 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:

typescript
// 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:

typescript
// 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:

shell
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 Page

2. Define Product Types

Create TypeScript type definitions for products in the unified type definition directory:

typescript
// 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:

typescript
// 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 ProductApiService

4. Create Product Internationalization Copy

Create copy for product module in the unified internationalization directory:

typescript
// 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:

  1. Filter Area - Supports filtering by product name, product code, category, status, etc.
  2. Data Display Area - Table view for desktop and card view for mobile
  3. Action Button Area - Add, batch delete, export and other functions
  4. Form Dialog - Product add/edit form
  5. 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-permission directive
  • Data Management: Supports pagination, filtering, sorting, status switching
  • Batch Operations: Supports batch delete and export
  • Form Validation: Complete form validation rules

Main Component Structure

vue
<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

typescript
// 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 productRoutes

Then import in main route file:

typescript
// 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 router

Backend 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.