Vben Admin: A Beginner's Guide to Simple Modifications

What is Vben Admin?

Vben Admin is a comprehensive solution for developing modern admin dashboards and management systems. It is built with Vue 3.0, Vite, and TypeScript, offering a robust and scalable foundation for enterprise applications.

Key Features:

  • Cutting-Edge Technology Stack: Developed using the latest front-end technologies, including Vue 3, Vite, and TypeScript.
  • Ready-to-Use: Comes with a complete set of admin dashboard features right out of the box.
  • Multi-UI Framework Support: Compatible with popular UI libraries such as Ant Design Vue, Element Plus, and Naive UI.
  • Full Internationalization: Includes a well-designed multi-language solution for seamless localization.

System Requirements

Before starting with Vben Admin, ensure that your development environment meets the following prerequisites:

  • Node.js: Version 20.15.0 or higher.
  • Package Manager: Only supports pnpm.

Project Setup and Installation

Vben Admin uses a Monorepo structure for project management. For more details, refer to the concept documentation. This guide focuses on the development of the web-antd version.

Project Directory Structure

Below is an overview of the key directories and files in the web-antd project:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apps/web-antd/src/
├── api/ # API integration layer
│ └── process/ # Categorized by functionality
│ └── index.ts # API definitions
├── router/ # Route configuration
│ └── routes/
│ ├── core/ # Core routes (e.g., login, 404)
│ ├── modules/ # Dynamic routes (functional modules)
│ └── static/ # Static routes
└── views/ # Page components
└── process/ # Functional module
├── components/ # Sub-components
│ ├── ProcessForm.vue
│ └── ProcessSearch.vue
├── create.vue # Create page
├── edit.vue # Edit page
└── index.vue # List page

1. Clone the Project Repository

To get the project source code, run the following commands:

1
2
3
4
5
# Clone the repository from GitHub
git clone https://github.com/vbenjs/vue-vben-admin.git

# Navigate to the project directory
cd vue-vben-admin

2. Install Dependencies

Follow these steps to install the necessary dependencies:

1
2
3
4
5
# Enable the project's specified pnpm version
corepack enable

# Install dependencies
pnpm install

3. Start the Project

Run the following commands to start the development server:

1
2
3
4
5
# Navigate to the Ant Design Vue version directory
cd apps/web-antd

# Start the development server
pnpm dev

Modify Language Settings

Vben Admin provides a comprehensive internationalization solution, supporting multi-language switching. For more details, refer to the official documentation. Below are the steps to modify the default language settings:

Change Default Language

To set the default language, modify the file apps/web-antd/src/preferences.ts as follows:

1
2
3
4
5
6
7
8
9
10
11
import { defineOverridesPreferences } from '@vben/preferences';

export const overridesPreferences = defineOverridesPreferences({
app: {
name: import.meta.env.VITE_APP_TITLE,
// Set the default language to English
locale: 'en-US',
// Other language options:
// 'zh-CN' - Simplified Chinese
},
});

Disable the Language Toggle Button

If the language toggle button is not needed, you can disable it in src/preferences.ts:

1
2
3
4
5
export const overridesPreferences = defineOverridesPreferences({
widget: {
languageToggle: false, // Disable the language toggle button
},
});

Notes

  1. After making changes, clear the browser cache to apply the updates.
  2. Language files are located in the src/locales/langs/ directory.

API Implementation Example

In Vben Admin, API-related code is recommended to be placed in the src/api directory and organized by functional modules (reference):

1
2
3
4
src/api/
├── core/ # Core APIs (e.g., login, permissions)
└── process/ # APIs for the process management module
└── index.ts # API definitions

Below is an example implementation for the process management module:

1
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
import { requestClient } from '#/api/request';

// Define API paths
enum Api {
Process = '/api/process', // Base path for the API
}

// Define data structure
export interface ProcessInfo {
id: string; // Process ID
name: string; // Process name
description?: string; // Process description
status: number; // Process status
createTime: string; // Creation time
updateTime: string; // Update time
}

// Define search parameters
export interface ProcessSearchParams {
// Search conditions
name?: string;
status?: string;
startTime?: string;
endTime?: string;

// Pagination parameters
page?: number;
pageSize?: number;

// Sorting parameters
sortField?: string;
sortOrder?: 'ascend' | 'descend';
}

/**
* @description: API utility functions
*/

// Fetch the list of processes
export function searchProcessList(params: ProcessSearchParams) {
return requestClient.get<{
items: ProcessInfo[];
total: number;
}>(Api.Process, { params });
}

// Retrieve a specific process
export function getProcess(id: string) {
return requestClient.get<ProcessInfo>(`${Api.Process}/${id}`);
}

// Create a new process
export function createProcess(data: Omit<ProcessInfo, 'id'>) {
return requestClient.post<ProcessInfo>(Api.Process, data);
}

// Update an existing process
export function updateProcess(id: string, data: Partial<ProcessInfo>) {
return requestClient.put<ProcessInfo>(`${Api.Process}/${id}`, data);
}

// Delete a process
export function deleteProcess(id: string) {
return requestClient.delete<boolean>(`${Api.Process}/${id}`);
}

Usage Instructions

  1. All API requests are handled uniformly using requestClient (reference).

ProcessSearch Component Implementation Guide

The search component is implemented using the Vben Form (reference).

Implementation

The component is defined as follows:

1
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
67
68
69
70
71
72
73
74
<script lang="ts" setup>
import { useVbenForm } from '#/adapter/form';
import type { ProcessSearchParams } from '#/api/process';
import dayjs from 'dayjs';

// Define component events
const emit = defineEmits<{
(e: 'search', params: ProcessSearchParams): void
}>();

// Use VbenForm
const [SearchForm] = useVbenForm({
// Default to expanded
collapsed: false,
// Handle form submission
handleSubmit: (values) => {
const { dateRange, ...rest } = values;
emit('search', {
...rest,
startTime: dateRange?.[0] ? dayjs(dateRange[0]).format('YYYY-MM-DD') : undefined,
endTime: dateRange?.[1] ? dayjs(dateRange[1]).format('YYYY-MM-DD') : undefined,
});
},
// Horizontal layout
layout: 'horizontal',
// Define form fields
schema: [
{
component: 'Input',
componentProps: {
placeholder: 'Enter process name',
allowClear: true,
},
fieldName: 'name',
label: 'Process Name'
},
{
component: 'Select',
componentProps: {
placeholder: 'Select status',
allowClear: true,
options: [
{ label: 'Active', value: '1' },
{ label: 'Inactive', value: '0' }
]
},
fieldName: 'status',
label: 'Status'
},
{
component: 'RangePicker',
componentProps: {
style: { width: '250px' }
},
fieldName: 'dateRange',
label: 'Creation Date'
}
],
// Show collapse button
showCollapseButton: true,
// Text for the search button
submitButtonOptions: {
text: 'Search'
},
// Support search on Enter key
submitOnEnter: true,
// Responsive grid configuration
wrapperClass: 'grid-cols-1 md:grid-cols-3'
});
</script>

<template>
<SearchForm />
</template>

Explanation

  1. Event Handling: The search event is emitted when the form is submitted, sending the search parameters (ProcessSearchParams) to the parent component.
  2. Dynamic Layout: The form uses a responsive grid system to adapt to different screen sizes, making it mobile-friendly.
  3. Fields:
    • Process Name: An input field for entering the process name.
    • Status: A dropdown to select the status (Active or Inactive).
    • Creation Date: A range picker for selecting a date range.
  4. Customizable Options:
    • The search button text is set to “Search.”
    • The form supports triggering the search using the Enter key.
  5. Collapsible Form: Includes an option to collapse the form for better user experience.

This implementation provides a clean, responsive, and easy-to-use search interface for process management.

src/views/process/index.vue

1
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<script lang="ts" setup>
import { useVbenForm } from '#/adapter/form'; // Import Vben Form for query form configuration.
import type { VxeGridProps } from '#/adapter/vxe-table'; // Import VxeGrid properties type definition.
import { useVbenVxeGrid } from '#/adapter/vxe-table'; // Import Vben Grid for the data table.
import { Page } from '@vben/common-ui'; // Import the layout container component.
import { Card, message } from 'ant-design-vue'; // Import UI components for styling and notifications.

interface ProcessInfo {
id: string; // Process ID
name: string; // Process name
status: string; // Process status
createTime: string; // Creation time
description: string; // Description of the process
}

// Query Form Configuration
// Defines a collapsible form with keyword, type, and date fields for filtering the data table.
const [QueryForm] = useVbenForm({
collapsed: false,
layout: 'horizontal',
handleSubmit: onSubmit, // Trigger table reload on form submission.
schema: [
{
component: 'Input',
fieldName: 'keyword',
label: 'Keyword',
componentProps: { placeholder: 'Enter keyword' },
},
{
component: 'Select',
fieldName: 'type',
label: 'Type',
componentProps: {
placeholder: 'Select type',
allowClear: true,
options: [
{ label: 'Option 1', value: '1' },
{ label: 'Option 2', value: '2' },
],
},
},
{
component: 'DatePicker',
fieldName: 'date',
label: 'Date',
},
],
showCollapseButton: true,
submitButtonOptions: { content: 'Search' },
wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3', // Responsive grid layout for form fields.
});

// Table Configuration
// The table displays process information with pagination, sorting, and action buttons for editing and deleting rows.
const gridOptions: VxeGridProps<ProcessInfo> = {
columns: [
{ title: 'No.', type: 'seq', width: 60 },
{ field: 'name', title: 'Name', width: 200 },
{ field: 'status', title: 'Status', width: 100 },
{ field: 'createTime', title: 'Creation Time', width: 180 },
{ field: 'description', title: 'Description', minWidth: 200 },
{
title: 'Actions',
width: 120,
fixed: 'right',
slots: { default: 'action' }, // Slot for custom action buttons.
},
],
toolbarConfig: {
refresh: true, // Refresh button
export: true, // Export button
custom: true, // Custom toolbar actions
},
proxyConfig: {
ajax: {
query: async ({ page }) => {
// Simulates an API call to fetch paginated process data.
try {
const res = await fetch(`/api/process/list?page=${page.currentPage}&pageSize=${page.pageSize}`);
const data = await res.json();
return { items: data.items, total: data.total };
} catch (error) {
message.error('Failed to fetch data');
return { items: [], total: 0 };
}
},
},
},
};

// Create grid instance and API for data reloading
const [Grid, gridApi] = useVbenVxeGrid({ gridOptions });

// Function to handle form submission and reload the table with updated filters.
function onSubmit(values: Record<string, any>) {
console.log('Query parameters:', values);
gridApi.reload(); // Refresh table data
}

// Action Handlers
// Provide feedback for edit and delete actions.
function handleEdit(row: ProcessInfo) {
message.success(`Edit: ${row.name}`);
}

function handleDelete(row: ProcessInfo) {
message.success(`Delete: ${row.name}`);
}
</script>

<template>
<Page auto-content-height>
<!-- Query Form -->
<Card class="mb-4">
<QueryForm />
</Card>

<!-- Data Table -->
<Card>
<Grid table-title="Data List">
<template #toolbar-tools>
<a-button type="primary" class="mr-2">Add</a-button>
</template>
<template #action="{ row }">
<a-button type="link" @click="handleEdit(row)">Edit</a-button>
<a-button type="link" @click="handleDelete(row)">Delete</a-button>
</template>
</Grid>
</Card>
</Page>
</template>

Key Features and Explanation:

  1. Query Form:

    • A collapsible form that includes fields for keyword, type, and date filtering.
    • Triggered submission calls onSubmit, which reloads the data table with new filters.
  2. Data Table:

    • Configured with pagination, sorting, and dynamic data loading from a simulated API call.
    • Includes action buttons for row-level operations (Edit/Delete).
  3. Dynamic API Integration:

    • Uses the proxyConfig feature of VxeGrid to fetch data dynamically based on pagination parameters.
  4. Responsive Layout:

    • The query form and table use grid-based responsive designs for optimal display across devices.

Adding a New Route for Process Management

To integrate the process management module into your Vben Admin project, you’ll need to update the routing configuration and localization files. Here’s how to do it step-by-step:

Step 1: Create a New Route

Add the following file: src/router/routes/modules/process.ts

1
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
import { BasicLayout } from '#/layouts'; // Import the basic layout for the module.
import { $t } from '#/locales'; // Import the localization helper function.
import type { RouteRecordRaw } from 'vue-router'; // Import the route type definition.

const routes: RouteRecordRaw[] = [
{
component: BasicLayout, // Use the basic layout for the process management module.
meta: {
icon: 'fluent:flow-16-regular', // Set the menu icon.
order: 100, // Define the order of the menu item.
title: $t('process.manager'), // Set the menu title (localized).
},
name: 'Process', // Name of the route.
path: '/process', // Base path for the module.
redirect: '/process/list', // Redirect to the list page by default.
children: [
{
name: 'ProcessList', // Name of the list route.
path: 'list', // Subpath for the list page.
component: () => import('#/views/process/index.vue'), // Lazy-load the list page component.
meta: {
title: $t('process.list'), // Set the title for the list page (localized).
},
},
// Add other child routes here if needed.
],
},
];

export default routes;

Step 2: Add Localization Keys

To ensure proper display of titles and labels, update the localization file src/locales/langs/en-US/process.json with the following content:

1
2
3
4
{
"manager": "Process management", // Title for the process management module.
"list": "Process list" // Title for the process list page.
}

This setup provides a clean and modular approach to adding new features to your Vben Admin project while supporting localization.

完成圖