Data Dictionary Documentation - Dictionary Management and Component Usage
Overview
This document details the data dictionary management system of the VJSP Vue3 framework. The data dictionary provides a unified enumeration value management solution, supporting centralized management and dynamic loading of status codes, type identifiers, and other data, ensuring data consistency and maintainability.
Dictionary Architecture
Core Features
- Unified Management: All enumeration data is centrally managed to avoid hardcoding
- Dynamic Loading: Supports runtime dynamic loading of dictionary data
- Intelligent Caching: Automatic caching mechanism to improve performance
- Type Safety: Complete TypeScript type definition support
- Error Handling: Comprehensive error handling and retry mechanisms
Technology Stack
- Pinia State Management: Dictionary data state management and caching
- Asynchronous Loading: Supports asynchronous retrieval and updating of dictionary data
- Component Integration: Deep integration with Element Plus component library
Dictionary Management Mechanism
Dictionary Data Storage
Dictionary data uses centralized storage management:
- Memory Cache: Dictionary data is cached in memory for faster access
- Automatic Expiration: Cached data automatically expires to ensure data timeliness
- Force Refresh: Supports manual forced refresh of dictionary data
Dictionary Loading Process
- Application Startup: Check cache validity
- Data Loading: Retrieve dictionary data from backend API
- Cache Update: Update memory cache and timestamp
- Error Handling: Handle network errors and retry logic
Caching Strategy
The framework implements intelligent caching strategies:
- Cache Duration: 5-minute automatic expiration
- Retry Mechanism: Maximum 3 retries with exponential backoff delay
- Concurrency Control: Prevent duplicate requests to avoid resource waste
Dictionary Utility Functions
Basic Dictionary Access
The framework provides safe dictionary access functions that automatically handle loading and errors:
getSafeDictLabel: Safely get dictionary labelgetSafeDictValue: Safely get dictionary valuegetSafeDictOptions: Safely get dictionary options listbatchGetDictLabels: Batch get dictionary labelshasDictType: Check if dictionary type exists
Dictionary State Management
Manage dictionary data through the dictionary store module:
getDictData: Get dictionary data (automatically handles caching)getDictByType: Get dictionary items by typegetDictLabel: Get dictionary labelgetDictValue: Get dictionary valuerefreshDictData: Refresh dictionary dataclearDictData: Clear dictionary cache
Dictionary Component Usage
Component Collection
The framework provides a complete dictionary component collection:
- DictSelect: Dictionary selector
- DictTag: Dictionary tag display
- DictRadio: Dictionary radio component
- DictCheckbox: Dictionary checkbox component
- DictSwitch: Dictionary switch component
- DictCascader: Dictionary cascader selector
Component Features
All dictionary components have the following features:
- Auto Loading: Automatically loads corresponding dictionary type data
- Error Handling: Handles dictionary data loading failures
- Type Safety: Complete TypeScript type support
- Style Consistency: Consistent with Element Plus component styling
Business Module Development Guide (Product Module)
1. Define Dictionary Types
Define product-related dictionary types in the dictionary management system:
product_status: Product status dictionaryproduct_category: Product category dictionaryproduct_type: Product type dictionary
2. Create Product Management Page
src/views/modules/product/list.vue
<template>
<div class="product-list">
<!-- Search Form -->
<el-form :model="queryParams" inline>
<el-form-item label="Product Status">
<DictSelect
v-model="queryParams.status"
dict-type="product_status"
placeholder="Please select product status"
clearable
/>
</el-form-item>
<el-form-item label="Product Category">
<DictSelect
v-model="queryParams.category"
dict-type="product_category"
placeholder="Please select product category"
clearable
/>
</el-form-item>
<el-button type="primary" @click="handleQuery">Query</el-button>
<el-button @click="resetQuery">Reset</el-button>
</el-form>
<!-- Data Table -->
<el-table :data="productList" v-loading="loading">
<el-table-column prop="productName" label="Product Name" />
<el-table-column prop="productCode" label="Product Code" />
<el-table-column prop="status" label="Product Status">
<template #default="{ row }">
<DictTag :value="row.status" dict-type="product_status" />
</template>
</el-table-column>
<el-table-column prop="category" label="Product Category">
<template #default="{ row }">
<DictTag :value="row.category" dict-type="product_category" />
</template>
</el-table-column>
<el-table-column prop="type" label="Product Type">
<template #default="{ row }">
<DictTag :value="row.type" dict-type="product_type" />
</template>
</el-table-column>
<el-table-column label="Actions" width="200">
<template #default="{ row }">
<el-button size="small" @click="handleEdit(row)">Edit</el-button>
<el-button size="small" type="danger" @click="handleDelete(row)">Delete</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useProductApi } from '@/api/modules/product'
const queryParams = ref({
status: '',
category: '',
productName: '',
})
const productList = ref([])
const loading = ref(false)
const loadProductList = async () => {
loading.value = true
try {
const response = await useProductApi().getList(queryParams.value)
productList.value = response.data.list
} finally {
loading.value = false
}
}
const handleQuery = () => {
loadProductList()
}
const resetQuery = () => {
queryParams.value = {
status: '',
category: '',
productName: '',
}
loadProductList()
}
onMounted(() => {
loadProductList()
})
</script>3. Product Creation/Editing Form
src/views/modules/product/form.vue
<template>
<el-form :model="formData" :rules="rules" ref="formRef" label-width="120px">
<el-form-item label="Product Name" prop="productName">
<el-input v-model="formData.productName" placeholder="Enter product name" />
</el-form-item>
<el-form-item label="Product Status" prop="status">
<DictRadio v-model="formData.status" dict-type="product_status" :options="statusOptions" />
</el-form-item>
<el-form-item label="Product Category" prop="category">
<DictSelect
v-model="formData.category"
dict-type="product_category"
placeholder="Select product category"
/>
</el-form-item>
<el-form-item label="Product Type" prop="type">
<DictCheckbox v-model="formData.type" dict-type="product_type" :options="typeOptions" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSubmit">Submit</el-button>
<el-button @click="handleCancel">Cancel</el-button>
</el-form-item>
</el-form>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const formRef = ref()
const formData = reactive({
productName: '',
status: '',
category: '',
type: [],
})
const rules = {
productName: [{ required: true, message: 'Product name is required', trigger: 'blur' }],
status: [{ required: true, message: 'Product status is required', trigger: 'change' }],
}
const handleSubmit = async () => {
try {
await formRef.value.validate()
// Submit form data
console.log('Form submitted:', formData)
router.push('/product/list')
} catch (error) {
console.error('Form validation failed:', error)
}
}
const handleCancel = () => {
router.push('/product/list')
}
</script>Advanced Dictionary Usage
Custom Dictionary Components
Create custom dictionary components for specific business needs:
<!-- src/components/DictColorTag.vue -->
<template>
<el-tag :color="getTagColor(value)" effect="dark">
{{ getDictLabel(value, dictType) }}
</el-tag>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { useDictStore } from '@/stores/dict'
interface Props {
value: string | number
dictType: string
}
const props = defineProps<Props>()
const dictStore = useDictStore()
const getTagColor = (value: string | number) => {
const colorMap = {
active: '#67C23A',
inactive: '#909399',
pending: '#E6A23C',
rejected: '#F56C6C',
}
return colorMap[value] || '#909399'
}
const getDictLabel = computed(() => {
return (value: string | number, type: string) => {
return dictStore.getDictLabel(type, value) || value
}
})
</script>Dictionary Data Validation
Implement dictionary-based form validation:
// src/utils/validation.ts
import { useDictStore } from '@/stores/dict'
export const createDictValidator = (dictType: string) => {
return (value: any) => {
const dictStore = useDictStore()
const dictOptions = dictStore.getDictByType(dictType)
const validValues = dictOptions.map(item => item.value)
if (!validValues.includes(value)) {
return new Error(`Invalid value for dictionary type: ${dictType}`)
}
return true
}
}
// Usage in form validation
const rules = {
status: [
{ required: true, message: 'Status is required' },
{ validator: createDictValidator('product_status'), trigger: 'change' },
],
}Performance Optimization
Lazy Loading Dictionaries
Load dictionaries on-demand to improve initial load performance:
// src/hooks/useLazyDict.ts
import { ref } from 'vue'
import { useDictStore } from '@/stores/dict'
export function useLazyDict(dictType: string) {
const dictStore = useDictStore()
const loading = ref(false)
const loaded = ref(false)
const loadDict = async () => {
if (loaded.value || dictStore.hasDictType(dictType)) {
return
}
loading.value = true
try {
await dictStore.loadDictData(dictType)
loaded.value = true
} finally {
loading.value = false
}
}
return {
loading,
loaded,
loadDict,
}
}Dictionary Preloading
Preload commonly used dictionaries during application initialization:
// src/utils/dictPreloader.ts
import { useDictStore } from '@/stores/dict'
export const preloadCommonDicts = async () => {
const dictStore = useDictStore()
const commonDictTypes = ['product_status', 'product_category', 'user_status', 'order_status']
await Promise.allSettled(commonDictTypes.map(type => dictStore.loadDictData(type)))
}Error Handling and Debugging
Dictionary Error Monitoring
Monitor dictionary loading errors and provide fallback mechanisms:
// src/utils/dictErrorHandler.ts
export class DictErrorHandler {
static handleLoadError(error: Error, dictType: string) {
console.error(`Failed to load dictionary: ${dictType}`, error)
// Send to error tracking service
if (import.meta.env.PROD) {
// Send to monitoring service
}
// Provide fallback data
return this.getFallbackDict(dictType)
}
static getFallbackDict(dictType: string) {
const fallbackDicts = {
product_status: [
{ label: 'Active', value: 'active' },
{ label: 'Inactive', value: 'inactive' },
],
// Add more fallback dictionaries
}
return fallbackDicts[dictType] || []
}
}Debugging Tools
Add debugging tools for dictionary development:
// src/utils/dictDebug.ts
export const dictDebug = {
logDictState: (dictType: string) => {
const dictStore = useDictStore()
console.log(`Dictionary [${dictType}]:`, dictStore.getDictByType(dictType))
},
monitorDictChanges: (dictType: string) => {
const dictStore = useDictStore()
watch(
() => dictStore.getDictByType(dictType),
(newDict, oldDict) => {
console.log(`Dictionary [${dictType}] changed:`, { old: oldDict, new: newDict })
}
)
},
}This comprehensive dictionary management system provides a robust foundation for handling enumeration data in the VJSP Vue3 framework, ensuring data consistency, type safety, and optimal performance across all business modules.
