VJSP Vue3 Frame - Development Standards and Best Practices
Overview
This document provides comprehensive development standards and best practice guidelines for the VJSP Vue3 Frame project. Based on actual project code and configurations, it covers core content including project architecture, development processes, code standards, and performance optimization, helping teams maintain code quality and development efficiency.
Project Architecture Design
Technology Stack Architecture
VJSP Vue3 Frame adopts a modern frontend technology stack:
- Core Framework: Vue 3 + TypeScript + Vite
- UI Component Library: Element Plus
- State Management: Pinia
- Routing Management: Vue Router 4
- Build Tool: Vite
- Code Standards: ESLint + Prettier
- Styling Solution: Less + Tailwind CSS
Directory Structure Design
The project uses a layered architecture design to ensure code maintainability and scalability:
src/
├── api/ # API interface layer
├── assets/ # Static resources
├── components/ # Public components
├── constants/ # Constant definitions
├── directives/ # Custom directives
├── hooks/ # Composition functions
├── layout/ # Layout components
├── locales/ # Internationalization resources
├── plugins/ # Plugin configurations
├── router/ # Routing configuration
├── stores/ # State management
├── styles/ # Style files
├── types/ # Type definitions
├── utils/ # Utility functions
└── views/ # Page componentsModular Design Principles
- Single Responsibility Principle: Each module/component is responsible for specific functionality
- Dependency Inversion Principle: High-level modules don't depend on low-level modules, both depend on abstractions
- Open/Closed Principle: Open for extension, closed for modification
- Interface Segregation Principle: Using multiple specific interfaces is better than using a single general interface
Development Process Standards
Code Commit Standards
The project adopts Conventional Commits specification:
# Commit format
<type>[optional scope]: <description>
# Examples
feat(user): Add user management functionality
fix(api): Fix login API exception
refactor(utils): Refactor cache utility functions
docs(readme): Update project documentationCommit Type Explanations:
feat: New featurefix: Bug fixdocs: Documentation updatestyle: Code formatting adjustmentsrefactor: Code refactoringtest: Testing related- `chore**: Build process or auxiliary tool changes
Branch Management Strategy
The project uses Git Flow branch management model:
main # Main branch, production environment code
├── develop # Development branch, feature integration
├── feature/ # Feature branches, new feature development
├── release/ # Release branches, version release preparation
└── hotfix/ # Hotfix branches, emergency bug fixesCode Review Process
- Feature Development: Develop on feature branches
- Local Testing: Test and verify functionality locally after completion
- PR Submission: Create Pull Request to develop branch
- Code Review: Team members conduct code review
- CI/CD: Automated build and testing
- Merge and Release: Merge and release after review approval
Code Standards Guide
TypeScript Standards
Type Definition Standards
// Interface definitions use PascalCase
interface UserInfo {
id: number
name: string
email: string
}
// Type aliases use PascalCase
type ApiResponse<T> = {
code: number
data: T
message: string
}
// Enums use PascalCase
enum UserStatus {
Active = 1,
Inactive = 0,
}Component Props Standards
// Use TypeScript interfaces to define Props
interface ProductCardProps {
product: Product
showActions?: boolean
onEdit?: (product: Product) => void
onDelete?: (productId: number) => void
}
// Use withDefaults to provide default values
const props = withDefaults(defineProps<ProductCardProps>(), {
showActions: true,
})Vue 3 Composition API Standards
Component Structure Standards
<template>
<!-- Template section -->
</template>
<script setup lang="ts">
// Import section
import { ref, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
// Type definitions
interface Product {
id: string
name: string
price: number
}
// Reactive data
const productList = ref<Product[]>([])
const loading = ref(false)
// Computed properties
const totalPrice = computed(() => {
return productList.value.reduce((sum, product) => sum + product.price, 0)
})
// Method definitions
const fetchProducts = async () => {
// Business logic
}
// Lifecycle
onMounted(() => {
fetchProducts()
})
// Expose to template
defineExpose({
productList,
fetchProducts,
})
</script>Composition Function Standards
// src/hooks/useProduct.ts
import { ref, computed } from 'vue'
import type { Product } from '@/types/api'
export function useProduct() {
const products = ref<Product[]>([])
// Composition function logic
const productCount = computed(() => products.value.length)
const addProduct = (product: Product) => {
products.value.push(product)
}
return {
products,
productCount,
addProduct,
}
}Component Naming Standards
File Naming
- PascalCase for components:
UserProfile.vue,ProductList.vue - kebab-case for multi-word:
user-profile.vue,product-list.vue - Prefix for specific types:
BaseButton.vue,AppHeader.vue
Component Naming Conventions
// Good examples
UserProfile.vue // User profile component
ProductList.vue // Product list component
BaseButton.vue // Base button component
AppHeader.vue // Application header component
// Avoid
userProfile.vue // Should be PascalCase
product_list.vue // Should use kebab-casePerformance Optimization Guidelines
Bundle Optimization
Code Splitting
// Route-based code splitting
const ProductDetail = defineAsyncComponent({
loader: () => import('@/views/product/Detail.vue'),
loadingComponent: LoadingSpinner,
delay: 200,
timeout: 3000,
})
// Component-based code splitting
const HeavyComponent = defineAsyncComponent(() => import('@/components/HeavyComponent.vue'))Tree Shaking Optimization
// Use named imports instead of namespace imports
import { debounce, throttle } from 'lodash-es' // Good
import _ from 'lodash-es' // Avoid
// Use ES modules for better tree shaking
import { formatDate } from '@/utils/date' // Good
import utils from '@/utils' // AvoidMemory Management
Event Listener Cleanup
// Proper event listener cleanup
onMounted(() => {
const handleResize = () => {
// Handle resize
}
window.addEventListener('resize', handleResize)
// Cleanup on unmount
onUnmounted(() => {
window.removeEventListener('resize', handleResize)
})
})Reactive Data Optimization
// Use shallowRef for large objects
const largeData = shallowRef({
/* large object */
})
// Use markRaw for non-reactive objects
const staticConfig = markRaw({
/* static config */
})
// Avoid unnecessary reactivity
const nonReactiveData = {
/* plain object */
}Testing Standards
Unit Testing
Component Testing
// Component unit test example
import { mount } from '@vue/test-utils'
import ProductCard from '@/components/ProductCard.vue'
describe('ProductCard', () => {
it('renders product information correctly', () => {
const product = {
id: 1,
name: 'Test Product',
price: 99.99,
}
const wrapper = mount(ProductCard, {
props: { product },
})
expect(wrapper.text()).toContain('Test Product')
expect(wrapper.text()).toContain('$99.99')
})
})Composition Function Testing
// Composition function test example
import { useProduct } from '@/hooks/useProduct'
describe('useProduct', () => {
it('manages product state correctly', () => {
const { products, addProduct } = useProduct()
const product = { id: 1, name: 'Test Product' }
addProduct(product)
expect(products.value).toHaveLength(1)
expect(products.value[0]).toEqual(product)
})
})E2E Testing
// E2E test example
describe('Product Management', () => {
it('should create a new product', () => {
cy.visit('/products')
cy.get('[data-testid="add-product-btn"]').click()
cy.get('[data-testid="product-name"]').type('New Product')
cy.get('[data-testid="save-product-btn"]').click()
cy.contains('Product created successfully').should('be.visible')
})
})Security Best Practices
Input Validation
// Input validation example
const validateEmail = (email: string): boolean => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
return emailRegex.test(email)
}
const validatePassword = (password: string): boolean => {
return (
password.length >= 8 && /[A-Z]/.test(password) && /[a-z]/.test(password) && /\d/.test(password)
)
}XSS Protection
<template>
<!-- Safe content rendering -->
<div v-html="sanitizedContent"></div>
<!-- Avoid direct user input rendering -->
<!-- <div v-html="userInput"></div> -->
<!-- Dangerous -->
</template>
<script setup lang="ts">
import DOMPurify from 'dompurify'
const sanitizedContent = computed(() => {
return DOMPurify.sanitize(rawContent.value)
})
</script>Documentation Standards
Code Documentation
/**
* Product management service
*
* Provides methods for managing product data including
* creation, retrieval, updating, and deletion operations.
*
* @example
* ```typescript
* const productService = new ProductService()
* const products = await productService.getProducts()
* ```
*/
class ProductService {
/**
* Retrieve all products
*
* @param filters - Optional filtering criteria
* @returns Promise resolving to product list
*/
async getProducts(filters?: ProductFilters): Promise<Product[]> {
// Implementation
}
}README Documentation
# Product Module
## Overview
This module handles product management functionality including CRUD operations.
## Features
- Product listing with pagination
- Product creation and editing
- Product search and filtering
## Usage
```typescript
import { useProduct } from '@/hooks/useProduct'
const { products, loading, fetchProducts } = useProduct()
```API Reference
See API Documentation for detailed API specifications.
## Deployment and CI/CD
### Build Optimization
```javascript
// vite.config.js
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks: {
vendor: ['vue', 'vue-router', 'pinia'],
ui: ['element-plus'],
utils: ['lodash-es', 'dayjs']
}
}
}
}
})Environment Configuration
// src/utils/env.ts
const env = {
isDevelopment: import.meta.env.DEV,
isProduction: import.meta.env.PROD,
apiBaseUrl: import.meta.env.VITE_API_BASE_URL,
appVersion: import.meta.env.VITE_APP_VERSION,
}
export default envMonitoring and Analytics
Performance Monitoring
// Performance monitoring setup
const performanceMonitor = {
trackPageLoad: () => {
performance.mark('page-loaded')
const navigation = performance.getEntriesByType('navigation')[0]
console.log('Page load time:', navigation.loadEventEnd - navigation.fetchStart)
},
trackComponentRender: (componentName: string) => {
performance.mark(`${componentName}-rendered`)
},
}Error Tracking
// Error tracking implementation
const errorTracker = {
captureError: (error: Error, context?: any) => {
console.error('Application error:', error, context)
// Send to error tracking service
if (import.meta.env.PROD) {
// Send to Sentry/LogRocket/etc.
}
},
}This comprehensive development standards guide ensures consistent code quality, maintainable architecture, and efficient development processes throughout the VJSP Vue3 Frame project lifecycle.
