Fork me on GitHub

Python系列之《Django-DRF-撰写前端功能》

Django使用前后端分离后,后端使用DRF,而前端则使用VUE来实现,本文学习下前端框架vueAdmin-template的使用。

GitHub:https://github.com/PanJiaChen/vueAdmin-template
demo地址:https://panjiachen.github.io/vueAdmin-template/#/dashboard

编译安装

1
2
3
4
5
6
# Clone project
$ git clone https://github.com/PanJiaChen/vueAdmin-template.git

# Install dependencies
$ cd vueAdmin-template
$ npm install # 会下载项目所有所需要的依赖包

运行vueAdmin

1
$ npm run dev

一、获取资源

1. 显示侧边栏

vim router/index.js

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
export const constantRouterMap = [
{ path: '/login', component: () => import('@/views/login/index'), hidden: true },
{ path: '/404', component: () => import('@/views/404'), hidden: true },

{
path: '/', # 这是网址根路由
component: Layout, # 调用模板
redirect: '/dashboard', # 路由URI名称
name: 'Dashboard', # 取一个名字
hidden: false, # 默认是否隐藏,否
children: [{
path: 'dashboard',
component: () => import('@/views/dashboard/index'), # 指定访问的文件
meta: { title: 'Dashboard', icon: 'example' }
}]
},
{
path: '/users', # 这是一级路由地址,
component: Layout, # 同样调用模板
# 没有redirect字段,因为users是多级标签
name: '用户管理', # 给它一个名字
meta: { title: '用户管理', icon: 'example' }, # 来一个meta信息
children: [ 子分类
{
path: 'list', # 二级路由地址,会与一级地址拼接成:/users/list
name: '用户列表', # 给它一个名字,用于显示
component: () => import('@/views/user/index'), # 指向user list所在的页面文件
meta: { title: '用户列表' }
},
{
path: 'group', # 二级路由地址,与上面同理
name: '用户组列表',
component: () => import('@/views/user/group'),
meta: { title: '用户组列表' }
}
]
},
{ path: '*', redirect: '/404', hidden: true }
]

完事,来看看页面效果:

2. Api接口GET方法

vim api/users/group.js

1
2
3
4
5
6
7
8
9
10
import request from '@/utils/request'

// 获取用户组信息
export function getGroupList(params) {
return request({
url: '/groups/',
method: 'get',
params
})
}

3. 创建view页面文件

前端页面使用饿了么开源的Element-ui框架,项目地址:http://element-cn.eleme.io/#/zh-CN/component/installation

vim views/user/group.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
<template>
<div class="user-group-container" style="padding: 10px;">

<div>
<!-- 用户列表搜索 -->
<el-col :span="8">
<el-input placeholder="请输入内容" size="small" prefix-icon="el-icon-search" v-model="params.name" @input="searchClick">
</el-input>
</el-col>
</div>

<!-- 显示用户列表 -->
<el-table :data="groupList" border style="width: 100%">
<el-table-column prop="id" label="ID"> </el-table-column>
<el-table-column prop="name" label="用户组"> </el-table-column>
<el-table-column prop="users" label="组成员"> </el-table-column>
</el-table>

<!-- 分页 -->
<center>
<el-pagination
background
layout="total, prev, pager, next, jumper"
@current-change="handleCurrentChange"
:total="totalNum">
</el-pagination>
</center>

</div>
</template>

<script>
import { getGroupList } from '@/api/users/group'
export default {
data() {
return {
groupList: [],
totalNum: 0,
params: {
page: 1,
name: ''
},
}
},
created() {
this.fetchData()
},
methods: {
fetchData() {
getGroupList(this.params).then(res => {
this.groupList = res.results
this.totalNum = res.count
})
},
handleCurrentChange(val) {
this.params.page = val
this.fetchData()
},
searchClick() {
this.params.page = 1
this.fetchData()
}
}
}
</script>

4. 查看页面效果

二、创建资源

1. Api接口POST方法

vim api/users/group.js

1
2
3
4
5
6
7
8
9
10
11
12
13
import request from '@/utils/request'

// 获取用户组信息
······

// 创建用户组
export function createGroup(data) {
return request({
url: '/groups/',
method: 'post',
data
})
}

2. Dialog表单+表单验证

vim views/user/group.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
    <div>
<!-- 用户列表搜索 -->
······
<!-- 添加用户组按钮 -->
<el-col :span="16" style="text-alige: right">
<el-button round type="primary" @click="handleAddGroupBtn" > 添加用户组 </el-button>
</el-col>
</div>

<!-- 显示用户列表 -->
·····
<!-- 添加用户组Dialog -->
<el-dialog title="添加用户组" :visible.sync="addGroupFormVisible">
<el-form :model="addGroupForm" :rules="addGroupFormRules" ref="addGroupForm" label-width="100px">
<el-form-item label="用户组名称" prop="name" :label-width="addGroupformLabelWidth">
<el-input v-model="addGroupForm.name" style="width: 300px;"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="addGroupFormVisible = false">取 消</el-button>
<el-button type="primary" @click="addGroupFormVisible = false">确 定</el-button>
</div>
</el-dialog>

<script>
import { getGroupList } from '@/api/users/group'
export default {
data() {
return {
······
addGroupFormVisible: false,
addGroupformLabelWidth: '200px',
addGroupForm: {
name: ''
},
addGroupFormRules: {
name: [
{ required: true, message: '请输入用户组名称', trigger: 'blur' },
{ min: 2, max: 8, message: '长度在 2 到 8 个字符', trigger: 'blur' }
]
}
}
},
······
methods: {
······
handleAddGroupBtn() {
this.addGroupFormVisible = true
}
}
}

</script>

3. 查看页面效果

4. 提交添加动作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<el-button type="primary" @click="handleAddGroupSubmit">确 定</el-button>

import { getGroupList, createGroup } from '@/api/users/group'

handleAddGroupSubmit() {
createGroup(this.addGroupForm).then(res => {
this.$message({
message: '用户组创建成功.',
type: 'success'
})
this.addGroupFormVisible = false //隐藏表单
this.$refs['addGroupForm'].resetFields() // 重置Form表单
this.fetchData() //刷新页面(其实就是重新获取数据)
// console.log(this.addGroupForm) // 有个BUG,表单验证后,没有拦截,就直接添加,等于没有验证效果。
})
}

增加用户组完成。

三、更新资源

1. Api接口PATCH方法

vim api/users/group.js

1
2
3
4
5
6
7
8
// 修改用户组
export function updateGroup(id, data) {
return({
url: '/groups/' + id + '/', //一定要加上ID
method: 'patch',
data
})
}

2. Dialog表单+表单验证

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
<!-- 显示用户列表 -->
······
<el-table-column label="操作">
<template slot-scope="scope">
<el-button type="warning" icon="el-icon-edit" circle @click="handleModifyGroupClick(scope.row)" ></el-button>
</template>
</el-table-column>


<!-- 更新用户组Dialog -->
<el-dialog title="更新用户组" :visible.sync="modifGroupFormVisible">
<el-form :model="modifGroupForm" :rules="GroupFormRules" ref="modifGroupForm" label-width="100px">
<el-form-item label="用户组名称" prop="name" :label-width="modifGroupformLabelWidth">
<el-input v-model="modifGroupForm.name" style="width: 300px;"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="modifGroupFormVisible = false">取 消</el-button>
<el-button type="primary" @click="handleModifGroupSubmit">确 定</el-button>
</div>
</el-dialog>


<script>
import { getGroupList, createGroup, updateGroup } from '@/api/users/group'
export default {
data() {
return {
······
GroupFormRules: {
name: [
{ required: true, message: '请输入用户组名称', trigger: 'blur' },
{ min: 2, max: 8, message: '长度在 2 到 8 个字符', trigger: 'blur' }
]
},
modifGroupFormVisible: false,
modifGroupformLabelWidth: '200px',
modifGroupForm: {
name: ''
}
}
},
······
methods: {
······
handleModifyGroupClick(obj) {
this.modifGroupFormVisible = true
this.modifGroupForm = obj
},
handleModifGroupSubmit() {
updateGroup(this.modifGroupForm.id, this.modifGroupForm).then(res => {
this.$message({
message: '用户组更新成功.',
type: 'success'
})
this.modifGroupFormVisible = false
this.$refs['modifGroupForm'].resetFields()
this.fetchData()
})
}
}
}
</script>

3. 查看页面效果

四、删除资源

1. Api接口DELETE方法

vim api/users/group.js

1
2
3
4
5
6
7
// 删除用户组
export function deleteGroup(id) {
return request({
url: '/groups/' + id + '/',
method: 'delete',
})
}

2. 绑定删除动作

vim views/uesr/group.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
<!-- 显示用户列表 -->
······
<el-table-column label="操作">
<template slot-scope="scope">
<el-button type="warning" icon="el-icon-edit" circle @click="handleModifyGroupClick(scope.row)" ></el-button>
<el-button type="danger" icon="el-icon-delete" circle @click="handleDeleteGroupClick(scope.row.id,scope.row.name)"></el-button>
</template>
</el-table-column>

<script>
import { getGroupList, createGroup, updateGroup, deleteGroup } from '@/api/users/group'
export default {
······
methods: {
······
handleDeleteGroupClick(id, name) {
this.$confirm('确定要删除 "' + name + '" 用户组吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteGroup(id).then(() => {
this.$message({
type: 'success',
message: '删除成功!'
})
this.fetchData()
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
}
}
}
</script>

3. 查看页面效果

五、遇到的问题

1. 验证问题

现象:在添加或更新资源时,设置验证提示2-8个字符,尽管校验错误,但此时点击确定,还是能添加进去;

还是能添加成功

问题解决:在调用create、update方法之前,先判断一下是否有验证通过,没有验证通过就提示一下;
具体解决代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
01x 目前还没解决,解决后贴上

02x 已经解决啦,代码如下:

<el-button type="primary" @click="handleAddGroupSubmit('addGroupForm')">确 定</el-button>

handleAddGroupSubmit(addGroupForm) {
this.$refs[addGroupForm].validate((valid) => { //添加认证判断即可
if (valid) {
createGroup(this.addGroupForm).then(res => {
this.$message({
message: '用户组创建成功.',
type: 'success'
})
this.addGroupFormVisible = false
this.$refs['addGroupForm'].resetFields()
this.fetchData()
})
} else {
return false
}
})
},

2. 字段信息同步

我也不太确定这算不算是个问题,在模态框上输入类容,页面上的数据会动态监听并且随之变化;

3. 验证信息不重置

第一步:在input框输入信息如下,出发验证错误

第二步:取消模态框,再点击其他更新按钮,会发现上一次的验证信息还在?

解决方法:

1
2
3
4
5
6
7
8
9
10
11
01x 设置这个参数不起作用,目前还没解决这个问题
this.$refs['modifGroupForm'].resetFields()

02x 解决啦,如下:(在打开模态框后重置From即可)
handleModifyGroupClick(obj) {
this.modifyGroupFormVisible = true
this.modifyGroupForm = obj
if (this.$refs['modifyGroupForm'] !== undefined) {
this.$refs['modifyGroupForm'].resetFields()
}
},

六、整个案例全部代码

1. API接口

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
import request from '@/utils/request'

// 获取用户组信息
export function getGroupList(params) {
return request({
url: '/groups/',
method: 'get',
params
})
}

// 创建用户组
export function createGroup(data) {
return request({
url: '/groups/',
method: 'post',
data
})
}

// 修改用户组
export function updateGroup(id, data) {
return request({
url: '/groups/' + id + '/',
method: 'patch',
data
})
}

// 删除用户组
export function deleteGroup(id) {
return request({
url: '/groups/' + id + '/',
method: 'delete',
id
})
}

2. 前端代码

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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
<template>
<div class="user-group-container" style="padding: 10px;">

<div>
<!-- 用户列表搜索 -->
<el-col :span="8">
<el-input placeholder="请输入内容" size="small" prefix-icon="el-icon-search" v-model="params.name" @input="searchClick">
</el-input>
</el-col>
<!-- 添加用户组按钮 -->
<el-col :span="16" style="text-alige: right">
<el-button plain type="primary" size="small" @click="handleAddGroupBtn" > 添加 </el-button>
</el-col>
</div>

<!-- 显示用户列表 -->
<el-table :data="groupList" border style="width: 100%">
<el-table-column prop="id" label="ID"> </el-table-column>
<el-table-column prop="name" label="用户组"> </el-table-column>
<el-table-column prop="users" label="组成员"> </el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button size="mini" @click="handleModifyGroupClick(scope.row)" plain>编辑</el-button>
<el-button size="mini" type="danger" @click="handleDeleteGroupClick(scope.row.id,scope.row.name)" plain>删除</el-button>
</template>
</el-table-column>
</el-table>

<!-- 添加用户组Dialog -->
<el-dialog title="添加用户组" :visible.sync="addGroupFormVisible">
<el-form :model="addGroupForm" :rules="GroupFormRules" ref="addGroupForm" label-width="100px">
<el-form-item label="用户组名称" prop="name" :label-width="addGroupformLabelWidth">
<el-input v-model="addGroupForm.name" style="width: 300px;"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="addGroupFormVisible = false">取 消</el-button>
<el-button type="primary" @click="handleAddGroupSubmit('addGroupForm')">确 定</el-button>
</div>
</el-dialog>


<!-- 更新用户组Dialog -->
<el-dialog title="更新用户组" :visible.sync="modifyGroupFormVisible">
<el-form :model="modifyGroupForm" :rules="GroupFormRules" ref="modifyGroupForm" label-width="100px">
<el-form-item label="用户组名称" prop="name" :label-width="modifyGroupformLabelWidth">
<el-input v-model="modifyGroupForm.name" style="width: 300px;"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="modifyGroupFormVisible = false">取 消</el-button>
<el-button type="primary" @click="handleModifyGroupSubmit('modifyGroupForm')">确 定</el-button>
</div>
</el-dialog>

<!-- 分页 -->
<center>
<el-pagination
background
layout="total, prev, pager, next, jumper"
@current-change="handleCurrentChange"
:total="totalNum">
</el-pagination>
</center>

</div>
</template>

<script>
import { getGroupList, createGroup, updateGroup, deleteGroup } from '@/api/users/group'
export default {
data() {
return {
groupList: [],
totalNum: 0,
params: {
page: 1,
name: ''
},
addGroupFormVisible: false,
addGroupformLabelWidth: '200px',
addGroupForm: {
name: ''
},
GroupFormRules: {
name: [
{ required: true, message: '请输入用户组名称', trigger: 'blur' },
{ min: 2, max: 8, message: '长度在 2 到 8 个字符', trigger: 'blur' }
]
},
modifyGroupFormVisible: false,
modifyGroupformLabelWidth: '200px',
modifyGroupForm: {
name: ''
}
}
},
created() {
this.fetchData()
},
methods: {
fetchData() {
getGroupList(this.params).then(res => {
this.groupList = res.results
this.totalNum = res.count
})
},
handleCurrentChange(val) {
this.params.page = val
this.fetchData()
},
searchClick() {
this.params.page = 1
this.fetchData()
},
handleAddGroupBtn() {
this.addGroupFormVisible = true
if (this.$refs['addGroupForm'] !== undefined) {
this.$refs['addGroupForm'].resetFields()
}
},
handleAddGroupSubmit(addGroupForm) {
this.$refs[addGroupForm].validate((valid) => {
if (valid) {
createGroup(this.addGroupForm).then(res => {
this.$message({
message: '用户组创建成功.',
type: 'success'
})
this.addGroupFormVisible = false
this.$refs['addGroupForm'].resetFields()
this.fetchData()
})
} else {
return false
}
})
},
handleModifyGroupClick(obj) {
this.modifyGroupFormVisible = true
this.modifyGroupForm = obj
if (this.$refs['modifyGroupForm'] !== undefined) {
this.$refs['modifyGroupForm'].resetFields()
}
},
handleModifyGroupSubmit(modifyGroupForm) {
this.$refs[modifyGroupForm].validate((valid) => {
if (valid) {
updateGroup(this.modifyGroupForm.id, this.modifyGroupForm).then(res => {
this.$message({
message: '用户组更新成功.',
type: 'success'
})
this.modifyGroupFormVisible = false
this.fetchData()
})
} else {
return false
}
})
},
handleDeleteGroupClick(id, name) {
this.$confirm('确定要删除 "' + name + '" 用户组吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteGroup(id).then(() => {
this.$message({
type: 'success',
message: '删除成功!'
})
this.fetchData()
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
}
}
}
</script>

3. 页面展示

本文主要讲解前端如何调用后面的接口,以及数据的增删改查,并没有将vueAdmin-template这个模板如何应用交代清楚,还望各位自行研究,或加入我们开源群,一起学习。

群已满,加我好友拉入群:(需备注:来至开源知识库)

-------------本文结束感谢您的阅读-------------