Service Providers β
Overview β
Core Functionality β
Service Providers (Providers) are one of the core features of the MineAdmin 3.0 frontend architecture, drawing inspiration from backend service provider design concepts to provide modular service registration and management mechanisms for frontend applications.
Key Features
- Global Service Registration: Register services to Vue's
globalProperties
orprovide/inject
system - Component Initialization: Automatically initialize and configure global components
- Plugin Configuration Management: Provide default configurations and parameter management for plugins
- Dependency Injection: Implement dependency relationship management between services
- Modular Architecture: Support organizing services by functional modules
Initialization Sequence β
Important Note
Service providers load during the early stages of application initialization, before libraries like pinia
, vue-router
, and vue-i18n
are initialized. Therefore, these library features cannot be used directly within service providers.
Initialization Order:
- Service provider scanning and registration β‘
- Pinia state management initialization
- Vue Router initialization
- Vue I18n internationalization initialization
- Main application launch
Architecture Design β
Directory Structure β
src/provider/
βββ dictionary/ # Dictionary service provider
β βββ index.ts # Service provider main file
β βββ data/ # Dictionary data files
βββ echarts/ # Chart service provider
β βββ index.ts
βββ plugins/ # Plugin configuration service provider
β βββ index.ts
βββ mine-core/ # Core component service provider
β βββ index.ts
βββ settings/ # System configuration service provider
β βββ index.ts
β βββ settings.config.ts
βββ toolbars/ # Toolbar service provider
βββ index.ts
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Auto-Discovery Mechanism β
During system startup, all subdirectories under src/provider/
are automatically scanned. Each subdirectory's index.ts
file is recognized as a service provider and automatically registered.
Built-in Services β
Dictionary Service β
Description: Provides unified data dictionary management functionality with support for multilingualism and theme color schemes.
Source Location:
- GitHub: src/provider/dictionary/
- Local:
/Users/zhuzhu/project/mineadmin/web/src/provider/dictionary/
Key Features:
- Supports multilingual internationalization identifiers
- Built-in theme color system
- Automatic type inference
- Reactive data updates
Dictionary Data Example (src/provider/dictionary/data/system-status.ts
):
import type { Dictionary } from '#/global'
export default [
{
label: 'Enabled',
value: 1,
i18n: 'dictionary.system.statusEnabled',
color: 'primary'
},
{
label: 'Disabled',
value: 2,
i18n: 'dictionary.system.statusDisabled',
color: 'danger'
},
] as Dictionary[]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Usage:
// Using dictionary data in components
import { useDictionary } from '@/composables/useDictionary'
const { getDictionary } = useDictionary()
const statusDict = getDictionary('system-status')
2
3
4
5
ECharts Service β
Description: Provides initialization, configuration, and theme management for the ECharts library.
Source Location:
- GitHub: src/provider/echarts/
- Local:
/Users/zhuzhu/project/mineadmin/web/src/provider/echarts/
Key Features:
- On-demand chart component imports to reduce bundle size
- Automatic theme adaptation (light/dark modes)
- Global instance registration with Vue
- Responsive chart resizing
Usage:
// Getting ECharts instance in components
import { useGlobal } from '@/composables/useGlobal'
const { $echarts } = useGlobal()
// Initializing charts
const chartInstance = $echarts.init(chartRef.value)
2
3
4
5
6
7
Reference component: MaEcharts
Plugins Service β
Description: Provides default configuration management for the MineAdmin plugin system, supporting unified plugin parameter configuration and management.
Source Location:
- GitHub: src/provider/plugins/
- Local:
/Users/zhuzhu/project/mineadmin/web/src/provider/plugins/
Key Features:
- Centralized plugin configuration management
- Default parameter registration
- Hot configuration updates
- Plugin dependency management
Reference documentation: Plugin System
MineCore Service β
Description: Initializes the MineAdmin core component library, providing global configuration and component registration services.
Source Location:
- GitHub: src/provider/mine-core/
- Local:
/Users/zhuzhu/project/mineadmin/web/src/provider/mine-core/
Managed Components:
ma-table
- Data table componentma-search
- Search form componentma-form
- Form componentma-pro-table
- Advanced table component
Usage:
import { useGlobal } from '@/composables/useGlobal'
const { $mineCore } = useGlobal()
const tableConfig = $mineCore.table
2
3
4
Settings Service β
Description: Provides global configuration parameter management for frontend applications, supporting separate configurations for development and production environments.
Source Location:
- GitHub: src/provider/settings/
- Local:
/Users/zhuzhu/project/mineadmin/web/src/provider/settings/
Configuration Files:
index.ts
- Default configuration (do not modify directly)settings.config.ts
- User custom configuration file
Configuration Example:
// settings.config.ts
export default {
// System basic configuration
app: {
name: 'MineAdmin',
version: '3.0.0',
logo: '/logo.png'
},
// API configuration
api: {
baseUrl: process.env.NODE_ENV === 'development'
? 'http://localhost:9501'
: 'https://api.example.com',
timeout: 10000
},
// Theme configuration
theme: {
primaryColor: '#409eff',
darkMode: 'auto'
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Development Guide β
Creating Basic Service Providers β
Step 1: Create service directory
mkdir src/provider/my-service
Step 2: Create service provider file (src/provider/my-service/index.ts
)
import type { App } from 'vue'
import type { ProviderService } from '#/global'
// Define service interface
interface MyService {
version: string
getName: () => string
setConfig: (config: any) => void
}
const provider: ProviderService.Provider<MyService> = {
name: 'myService',
init() {
console.log('MyService initializing...')
},
setProvider(app: App) {
const service: MyService = {
version: '1.0.0',
getName: () => 'My Custom Service',
setConfig: (config) => {
console.log('Configuration updated:', config)
}
}
// Register to global properties
app.config.globalProperties.$myService = service
// Or use provide/inject
app.provide('myService', service)
},
getProvider() {
return useGlobal().$myService
}
}
export default provider
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Creating Advanced Service Providers with Configuration β
import type { App } from 'vue'
import type { ProviderService } from '#/global'
// Service configuration interface
interface ServiceConfig {
apiUrl: string
timeout: number
retries: number
}
// Service instance interface
interface AdvancedService {
config: ServiceConfig
request: (url: string) => Promise<any>
updateConfig: (newConfig: Partial<ServiceConfig>) => void
}
const provider: ProviderService.Provider<AdvancedService> = {
name: 'advancedService',
config: {
enabled: true,
priority: 10,
dependencies: ['settings'] // Depends on settings service
},
async init() {
// Async initialization logic
await this.loadExternalLibrary()
},
setProvider(app: App) {
const defaultConfig: ServiceConfig = {
apiUrl: '/api/v1',
timeout: 5000,
retries: 3
}
const service: AdvancedService = {
config: { ...defaultConfig },
async request(url: string) {
// Implement request logic
return fetch(`${this.config.apiUrl}${url}`, {
timeout: this.config.timeout
})
},
updateConfig(newConfig) {
Object.assign(this.config, newConfig)
}
}
app.config.globalProperties.$advancedService = service
},
getProvider() {
return useGlobal().$advancedService
},
async loadExternalLibrary() {
// Logic for loading external dependencies
}
}
export default provider
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
Using Service Providers β
In Vue Components:
<template>
<div>
<h3>{{ serviceName }}</h3>
<p>Version: {{ version }}</p>
</div>
</template>
<script setup lang="ts">
import { useGlobal } from '@/composables/useGlobal'
const { $myService } = useGlobal()
const serviceName = $myService.getName()
const version = $myService.version
// Update configuration
$myService.setConfig({ theme: 'dark' })
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
In Composables:
// composables/useMyService.ts
import { useGlobal } from '@/composables/useGlobal'
export function useMyService() {
const { $myService } = useGlobal()
const updateServiceConfig = (config: any) => {
$myService.setConfig(config)
}
return {
service: $myService,
updateServiceConfig
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Best Practices β
1. Naming Conventions β
- Service provider names use camelCase format
- Directory names use kebab-case format
- Global properties use
$
prefix
2. Type Safety β
// Extend global property types
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$myService: MyService
}
}
2
3
4
5
6
3. Dependency Management β
const provider: ProviderService.Provider = {
name: 'dependentService',
config: {
dependencies: ['settings', 'dictionary']
},
// ...other configurations
}
2
3
4
5
6
7
4. Error Handling β
setProvider(app: App) {
try {
// Service initialization logic
app.config.globalProperties.$service = createService()
} catch (error) {
console.error(`Service ${this.name} initialization failed:`, error)
// Provide fallback solution
app.config.globalProperties.$service = createFallbackService()
}
}
2
3
4
5
6
7
8
9
10
Service Management β
Disabling Service Providers β
const provider: ProviderService.Provider = {
name: 'optionalService',
config: {
enabled: false // Disable this service
},
// ...other configurations
}
2
3
4
5
6
7
Removing Service Providers β
Delete the corresponding service provider directory:
rm -rf src/provider/unwanted-service
Debugging Service Providers β
const provider: ProviderService.Provider = {
name: 'debugService',
init() {
if (process.env.NODE_ENV === 'development') {
console.log(`[Provider] ${this.name} initialization complete`)
}
},
setProvider(app: App) {
// Add debug info in development environment
if (process.env.NODE_ENV === 'development') {
window.__DEBUG_PROVIDERS__ = window.__DEBUG_PROVIDERS__ || {}
window.__DEBUG_PROVIDERS__[this.name] = this
}
// Normal service registration logic
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Frequently Asked Questions β
Issue | Cause | Solution |
---|---|---|
Service not registered | Missing index.ts file or unimplemented required interfaces | Check file existence and interface implementation |
Cannot use Pinia | Service providers initialize before Pinia | Move Pinia-related logic to components or composables |
Service dependency conflicts | Circular dependencies or incorrect dependency order | Redesign dependencies or use event bus |
Type inference errors | Global property types not properly extended | Add TypeScript module declarations |
Hot reload fails | Service caching issues | Restart development server |
Related Resources β
Source Code References:
- GitHub Repository: MineAdmin Source
- Service Provider Directory: web/src/provider/
- Local Source:
/Users/zhuzhu/project/mineadmin/web/src/provider/
Related Documentation: