1
0
mirror of https://github.com/PanJiaChen/vue-element-admin.git synced 2026-01-07 23:47:00 +08:00
This commit is contained in:
choi-wan 2025-12-01 16:45:28 +08:00
parent 6858a9ad67
commit 1d4063d221
11 changed files with 574 additions and 0 deletions

View File

@ -11,6 +11,8 @@ import componentsRouter from './modules/components'
import chartsRouter from './modules/charts'
import tableRouter from './modules/table'
import nestedRouter from './modules/nested'
import userRouter from './modules/user'
import classRouter from './modules/class'
/**
* Note: sub-menu only appear when route children.length >= 1
@ -189,6 +191,8 @@ export const asyncRoutes = [
chartsRouter,
nestedRouter,
tableRouter,
userRouter,
classRouter,
{
path: '/example',

View File

@ -0,0 +1,37 @@
/** Class Management Router Module **/
import Layout from '@/layout'
const classRouter = {
path: '/class',
component: Layout,
redirect: '/class/list',
name: 'Class',
meta: {
title: 'Class Management',
icon: 'el-icon-document'
},
children: [
{
path: 'list',
component: () => import('@/views/class/list'),
name: 'ClassList',
meta: { title: 'Class List' }
},
{
path: 'create',
component: () => import('@/views/class/create'),
name: 'ClassCreate',
meta: { title: 'Create Class' }
},
{
path: 'edit/:id(\d+)',
component: () => import('@/views/class/edit'),
name: 'ClassEdit',
meta: { title: 'Edit Class', noCache: true },
hidden: true
}
]
}
export default classRouter

View File

@ -0,0 +1,37 @@
/** User Management Router Module **/
import Layout from '@/layout'
const userRouter = {
path: '/user',
component: Layout,
redirect: '/user/list',
name: 'User',
meta: {
title: 'User Management',
icon: 'user'
},
children: [
{
path: 'list',
component: () => import('@/views/user/list'),
name: 'UserList',
meta: { title: 'User List' }
},
{
path: 'create',
component: () => import('@/views/user/create'),
name: 'UserCreate',
meta: { title: 'Create User' }
},
{
path: 'edit/:id(\d+)',
component: () => import('@/views/user/edit'),
name: 'UserEdit',
meta: { title: 'Edit User', noCache: true },
hidden: true
}
]
}
export default userRouter

View File

@ -0,0 +1,75 @@
<template>
<el-form ref="classForm" :model="classItem" label-width="100px" label-position="left">
<el-form-item label="Name" prop="name" :rules="[{ required: true, message: 'Please input class name', trigger: 'blur' }]">
<el-input v-model="classItem.name" placeholder="Class Name" />
</el-form-item>
<el-form-item label="Description" prop="description" :rules="[{ required: true, message: 'Please input class description', trigger: 'blur' }]">
<el-input
v-model="classItem.description"
:autosize="{ minRows: 2, maxRows: 4}"
type="textarea"
placeholder="Class Description"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm">Confirm</el-button>
<el-button @click="cancel">Cancel</el-button>
</el-form-item>
</el-form>
</template>
<script>
const defaultClass = {
id: 0,
name: '',
description: ''
}
export default {
name: 'ClassForm',
props: {
isEdit: {
type: Boolean,
default: false
}
},
data() {
return {
classItem: Object.assign({}, defaultClass)
}
},
created() {
if (this.isEdit) {
// In a real application, you would fetch the class data from an API
// For this demo, we'll use mock data
const classId = parseInt(this.$route.params.id)
this.classItem = {
id: classId,
name: `Class ${classId}`,
description: `Description for Class ${classId}`
}
}
},
methods: {
submitForm() {
this.$refs['classForm'].validate((valid) => {
if (valid) {
// In a real application, you would send the data to an API
// For this demo, we'll just show a success message
this.$message({
type: 'success',
message: this.isEdit ? 'Class updated successfully!' : 'Class created successfully!'
})
// Redirect to class list page
this.$router.push('/class/list')
} else {
return false
}
})
},
cancel() {
this.$router.push('/class/list')
}
}
}
</script>

View File

@ -0,0 +1,16 @@
<template>
<div>
<ClassForm :is-edit="false" />
</div>
</template>
<script>
import ClassForm from './components/ClassForm'
export default {
name: 'ClassCreate',
components: {
ClassForm
}
}
</script>

16
src/views/class/edit.vue Normal file
View File

@ -0,0 +1,16 @@
<template>
<div>
<ClassForm :is-edit="true" />
</div>
</template>
<script>
import ClassForm from './components/ClassForm'
export default {
name: 'ClassEdit',
components: {
ClassForm
}
}
</script>

123
src/views/class/list.vue Normal file
View File

@ -0,0 +1,123 @@
<template>
<div class="app-container">
<el-button type="primary" @click="handleAddClass">New Class</el-button>
<el-table :data="classList" style="width: 100%;margin-top:30px;" border>
<el-table-column align="center" label="ID" width="120">
<template slot-scope="scope">
{{ scope.row.id }}
</template>
</el-table-column>
<el-table-column align="center" label="Name" width="180">
<template slot-scope="scope">
{{ scope.row.name }}
</template>
</el-table-column>
<el-table-column align="center" label="Description">
<template slot-scope="scope">
{{ scope.row.description }}
</template>
</el-table-column>
<el-table-column align="center" label="Operations">
<template slot-scope="scope">
<el-button type="primary" size="small" @click="handleEdit(scope)">Edit</el-button>
<el-button type="danger" size="small" @click="handleDelete(scope)">Delete</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog :visible.sync="dialogVisible" :title="dialogType==='edit'?'Edit Class':'New Class'">
<el-form :model="classItem" label-width="80px" label-position="left">
<el-form-item label="Name">
<el-input v-model="classItem.name" placeholder="Class Name" />
</el-form-item>
<el-form-item label="Description">
<el-input
v-model="classItem.description"
:autosize="{ minRows: 2, maxRows: 4}"
type="textarea"
placeholder="Class Description"
/>
</el-form-item>
</el-form>
<div style="text-align:right;">
<el-button type="danger" @click="dialogVisible=false">Cancel</el-button>
<el-button type="primary" @click="confirmClass">Confirm</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
const defaultClass = {
id: 0,
name: '',
description: ''
}
export default {
data() {
return {
classItem: Object.assign({}, defaultClass),
classList: [
{ id: 1, name: 'Class 1', description: 'First class description' },
{ id: 2, name: 'Class 2', description: 'Second class description' },
{ id: 3, name: 'Class 3', description: 'Third class description' }
],
dialogVisible: false,
dialogType: 'new'
}
},
methods: {
handleAddClass() {
this.classItem = Object.assign({}, defaultClass)
this.dialogType = 'new'
this.dialogVisible = true
},
handleEdit(scope) {
this.classItem = Object.assign({}, scope.row)
this.dialogType = 'edit'
this.dialogVisible = true
},
handleDelete(scope) {
this.$confirm('Are you sure to delete this class?', 'Warning', {
confirmButtonText: 'Yes',
cancelButtonText: 'No',
type: 'warning'
}).then(() => {
const index = this.classList.findIndex(item => item.id === scope.row.id)
this.classList.splice(index, 1)
this.$message({
type: 'success',
message: 'Deleted successfully!'
})
}).catch(() => {
this.$message({
type: 'info',
message: 'Delete canceled'
})
})
},
confirmClass() {
if (this.dialogType === 'new') {
// Generate a new ID
const maxId = Math.max(...this.classList.map(item => item.id))
this.classItem.id = maxId + 1
// Add to list
this.classList.push(Object.assign({}, this.classItem))
} else {
// Update existing class
const index = this.classList.findIndex(item => item.id === this.classItem.id)
if (index !== -1) {
this.classList.splice(index, 1, Object.assign({}, this.classItem))
}
}
this.dialogVisible = false
this.$message({
type: 'success',
message: this.dialogType === 'new' ? 'Created successfully!' : 'Updated successfully!'
})
}
}
}
</script>

View File

@ -0,0 +1,89 @@
<template>
<el-form ref="userForm" :model="user" label-width="100px" label-position="left">
<el-form-item label="Name" prop="name" :rules="[{ required: true, message: 'Please input user name', trigger: 'blur' }]">
<el-input v-model="user.name" placeholder="User Name" />
</el-form-item>
<el-form-item label="Email" prop="email" :rules="[{ required: true, message: 'Please input user email', trigger: 'blur' }, { type: 'email', message: 'Please enter a valid email address', trigger: 'blur' }]">
<el-input v-model="user.email" placeholder="User Email" />
</el-form-item>
<el-form-item label="Class" prop="classId" :rules="[{ required: true, message: 'Please select a class', trigger: 'change' }]">
<el-select v-model="user.classId" placeholder="Select Class">
<el-option
v-for="cls in classList"
:key="cls.id"
:label="cls.name"
:value="cls.id"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm">Confirm</el-button>
<el-button @click="cancel">Cancel</el-button>
</el-form-item>
</el-form>
</template>
<script>
const defaultUser = {
id: 0,
name: '',
email: '',
classId: 0,
className: ''
}
export default {
name: 'UserForm',
props: {
isEdit: {
type: Boolean,
default: false
}
},
data() {
return {
user: Object.assign({}, defaultUser),
classList: [
{ id: 1, name: 'Class 1' },
{ id: 2, name: 'Class 2' },
{ id: 3, name: 'Class 3' }
]
}
},
created() {
if (this.isEdit) {
// In a real application, you would fetch the user data from an API
// For this demo, we'll use mock data
const userId = parseInt(this.$route.params.id)
this.user = {
id: userId,
name: `User ${userId}`,
email: `user${userId}@example.com`,
classId: Math.floor(Math.random() * 3) + 1,
className: `Class ${Math.floor(Math.random() * 3) + 1}`
}
}
},
methods: {
submitForm() {
this.$refs['userForm'].validate((valid) => {
if (valid) {
// In a real application, you would send the data to an API
// For this demo, we'll just show a success message
this.$message({
type: 'success',
message: this.isEdit ? 'User updated successfully!' : 'User created successfully!'
})
// Redirect to user list page
this.$router.push('/user/list')
} else {
return false
}
})
},
cancel() {
this.$router.push('/user/list')
}
}
}
</script>

14
src/views/user/create.vue Normal file
View File

@ -0,0 +1,14 @@
<template>
<div class="app-container">
<user-form :is-edit="false" />
</div>
</template>
<script>
import UserForm from './components/UserForm'
export default {
name: 'CreateUser',
components: { UserForm }
}
</script>

15
src/views/user/edit.vue Normal file
View File

@ -0,0 +1,15 @@
<template>
<div>
<UserForm :is-edit="true" />
</div>
</template>
<script>
import UserForm from './components/UserForm'
export default {
name: 'EditUser',
components: { UserForm }
}
</script>

148
src/views/user/list.vue Normal file
View File

@ -0,0 +1,148 @@
<template>
<div class="app-container">
<el-button type="primary" @click="handleAddUser">New User</el-button>
<el-table :data="userList" style="width: 100%;margin-top:30px;" border>
<el-table-column align="center" label="ID" width="120">
<template slot-scope="scope">
{{ scope.row.id }}
</template>
</el-table-column>
<el-table-column align="center" label="Name" width="180">
<template slot-scope="scope">
{{ scope.row.name }}
</template>
</el-table-column>
<el-table-column align="center" label="Email">
<template slot-scope="scope">
{{ scope.row.email }}
</template>
</el-table-column>
<el-table-column align="center" label="Class">
<template slot-scope="scope">
{{ scope.row.className }}
</template>
</el-table-column>
<el-table-column align="center" label="Operations">
<template slot-scope="scope">
<el-button type="primary" size="small" @click="handleEdit(scope)">Edit</el-button>
<el-button type="danger" size="small" @click="handleDelete(scope)">Delete</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog :visible.sync="dialogVisible" :title="dialogType==='edit'?'Edit User':'New User'">
<el-form :model="user" label-width="80px" label-position="left">
<el-form-item label="Name">
<el-input v-model="user.name" placeholder="User Name" />
</el-form-item>
<el-form-item label="Email">
<el-input v-model="user.email" placeholder="User Email" />
</el-form-item>
<el-form-item label="Class">
<el-select v-model="user.classId" placeholder="Select Class">
<el-option
v-for="cls in classList"
:key="cls.id"
:label="cls.name"
:value="cls.id"
/>
</el-select>
</el-form-item>
</el-form>
<div style="text-align:right;">
<el-button type="danger" @click="dialogVisible=false">Cancel</el-button>
<el-button type="primary" @click="confirmUser">Confirm</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
const defaultUser = {
id: 0,
name: '',
email: '',
classId: 0,
className: ''
}
export default {
data() {
return {
user: Object.assign({}, defaultUser),
userList: [
{ id: 1, name: 'John Doe', email: 'john@example.com', classId: 1, className: 'Class 1' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', classId: 2, className: 'Class 2' },
{ id: 3, name: 'Bob Johnson', email: 'bob@example.com', classId: 3, className: 'Class 3' }
],
classList: [
{ id: 1, name: 'Class 1' },
{ id: 2, name: 'Class 2' },
{ id: 3, name: 'Class 3' }
],
dialogVisible: false,
dialogType: 'new'
}
},
methods: {
handleAddUser() {
this.user = Object.assign({}, defaultUser)
this.dialogType = 'new'
this.dialogVisible = true
},
handleEdit(scope) {
this.user = Object.assign({}, scope.row)
this.dialogType = 'edit'
this.dialogVisible = true
},
handleDelete(scope) {
this.$confirm('Are you sure to delete this user?', 'Warning', {
confirmButtonText: 'Yes',
cancelButtonText: 'No',
type: 'warning'
}).then(() => {
const index = this.userList.findIndex(item => item.id === scope.row.id)
this.userList.splice(index, 1)
this.$message({
type: 'success',
message: 'Deleted successfully!'
})
}).catch(() => {
this.$message({
type: 'info',
message: 'Delete canceled'
})
})
},
confirmUser() {
if (this.dialogType === 'new') {
// Generate a new ID
const maxId = Math.max(...this.userList.map(item => item.id))
this.user.id = maxId + 1
// Get class name
const selectedClass = this.classList.find(cls => cls.id === this.user.classId)
this.user.className = selectedClass ? selectedClass.name : ''
// Add to list
this.userList.push(Object.assign({}, this.user))
} else {
// Update existing user
const index = this.userList.findIndex(item => item.id === this.user.id)
if (index !== -1) {
// Get class name
const selectedClass = this.classList.find(cls => cls.id === this.user.classId)
this.user.className = selectedClass ? selectedClass.name : ''
// Update the user
this.userList.splice(index, 1, Object.assign({}, this.user))
}
}
this.dialogVisible = false
this.$message({
type: 'success',
message: this.dialogType === 'new' ? 'Created successfully!' : 'Updated successfully!'
})
}
}
}
</script>