历时2周左右,我终于完成了我的毕业项目。虽说页面不是特别美观,但是对于一个后端开发人员来说,我觉得已经是很不错了。今天主要分享前端页面的实现,以及如何对接后端的接口,先看项目效果。
目录
一、页面展示
登录界面
管理界面
数据操作
二、代码展示
登录页代码
<template>
<div class="login_page">
<div class="logo">
<div class="txt">九江</div>
<img class="img" src="../assets/logo.jpg" alt="">
<div class="txt">科技</div>
</div>
<div class="login-container">
<h3>自动化测试管理平台</h3>
<el-form label-width="100px" v-model="login">
<el-form-item label="用户名">
<el-input v-model="login.phone" clearable placeholder="输入不少于三位的字母和数字"></el-input>
</el-form-item>
<el-form-item label="口令">
<el-input v-model="login.pwd" show-password clearable placeholder="输入不少于六位的字母和数字"></el-input>
</el-form-item>
<el-form-item class="form_foot">
<el-checkbox label="是否记住" v-model="remember" style="margin-right:25px"></el-checkbox>
<el-button type="primary" size="medium" native-type="button" @click="loginHandler" style="background: #191970;border: none">登录</el-button>
<el-button type="danger" size="medium" native-type="button" @click="cover" style="border: none">重置</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
export default {
phone: 'Login',
data () {
return {
login: {
phone: '',
pwd: ''
},
remember: false
}
},
methods: {
loginHandler () {
console.info(this.login, this.remember)
if (!/\w{3,}/.test(this.login.phone)) {
this.$message({
message: '用户名不能为空或者不合法',
type: Error
})
return false
}
if (!/\w{6,}/.test(this.login.pwd)) {
this.$message({
message: '口令不能为空或者不合法',
type: Error
})
return false
}
this.$http.post('/user/login/', this.login).then(resp => {
if (resp.status === 200) {
const { token, data } = resp.data
sessionStorage.setItem('token', token)
// data=>{nick_name, phone, addr, sex}
sessionStorage.setItem('user', JSON.stringify(data))
this.$router.push('/')
} else {
this.$message.error(resp.data.msg)
}
})
},
cover () {
this.login.phone = ''
this.login.pwd = ''
}
}
}
</script>
<style scoped>
.login_page {
height: 100%;
width: 100%;
background-image:url(../assets/6.jpg);
background-size: cover;
}
.logo{
display: flex;
/* width: 100px; */
height: 100px;
position: relative;
top: 28%;
border-radius: 50%;
justify-content: center;
}
.txt{
/* width: 100px; */
height: 100px;
line-height: 100px;
font-size: 50px;
background: #EEE url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAHklEQVQImWNkYGBgYGD4//8/A5wF5SBYyAr+//8PAPOCFO0Q2zq7AAAAAElFTkSuQmCC) repeat;
text-shadow: 5px -5px #00008B, 4px -4px black;
font-weight: bold;
-webkit-text-fill-color: transparent;
-webkit-background-clip: text;
}
.img{
width: 100px;
height: 100px;
border-radius: 50%;
margin: 0 20px;
}
.login-container {
width: 400px;
height: 280px;
border: 1px solid #fff;
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 20px 20px 0 0;
overflow: hidden;
}
.login-container h3 {
margin: 0;
padding: 15px;
background-color:#00688B;
color: white;
text-align: center;
}
.el-row {
padding: 10px;
}
.title {
text-align: left;
padding-left: 20px;
}
.el-form{
padding: 20px;
}
.el-form .el-button{
/* position: absolute; */
/* right: 5px; */
}
/* .form_foot{
display: flex;
justify-content: space-between;
} */
.form_button{
display: flex;
justify-content: flex-end;
}
</style>
管理页代码
<template>
<div>
<breadcrumb title="用户中心"></breadcrumb>
<div class="search-container">
<el-button type="primary" slot="append" @click="loadsugs()">用户信息</el-button>
</div>
<el-table :data="datas" border stripe height="380px">
<el-table-column prop="id" label="序号" width="120px" align="center"></el-table-column>
<el-table-column prop="phone" label="手机号" width="140px" align="center"></el-table-column>
<el-table-column prop="name" label="姓名" width="160px" align="center"></el-table-column>
<el-table-column prop="sex" label="性别" width="100px" align="center"></el-table-column>
<el-table-column prop="age" label="年龄" width="100px" align="center"></el-table-column>
<el-table-column prop="role" label="角色" width="100px" align="center"></el-table-column>
<el-table-column prop="email" label="邮箱" width="320px" align="center"></el-table-column>
<el-table-column prop="header" label="头像" width="180px" align="center">
<template slot-scope="scope">
<img style="width:30px;height:30px;border-radius:50%;" :src="'http://127.0.0.1:8000/m/'+scope.row.header">
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: 'AppUser',
data () {
return {
datas: []
}
},
mounted () {
this.loadsugs()
},
methods: {
tableRowClassName ({ row, rowIndex }) {
if (rowIndex % 2 === 1) {
return 'info-row'
} else if (rowIndex % 2 === 0) {
return 'success-row'
}
return ''
},
loadsugs () {
this.$http.get('/user/get_user_info/').then(resp => {
this.datas = resp.data
})
}
}
}
</script>
<style>
.el-table {
width: 100%;
}
.search-container {
height: 50px;
display: flex;
align-items: center;
}
.el-autocomplete {
width: 500px;
}
.el-table .warning-row {
background: oldlace;
}
.el-table .success-row {
background: #f0f9eb;
}
</style>
操作页代码
<template>
<div>
<breadcrumb title="用户操作"></breadcrumb>
<div class="search-container">
<el-button type="primary" @click="loaddata()">刷新</el-button>
</div>
<el-table :data="datas" border stripe height="370px">
<el-table-column prop="id" label="序号" width="50px" align="center"></el-table-column>
<el-table-column prop="phone" label="手机号" width="140px" align="center"></el-table-column>
<el-table-column prop="name" label="姓名" width="120px" align="center"></el-table-column>
<el-table-column prop="sex" label="性别" width="75px" align="center"></el-table-column>
<el-table-column prop="age" label="年龄" width="75px" align="center"></el-table-column>
<el-table-column prop="role" label="角色" width="160px" align="center"></el-table-column>
<el-table-column prop="email" label="邮箱" width="280px" align="center"></el-table-column>
<el-table-column prop="is_active" label="状态" width="120px" align="center"></el-table-column>
<el-table-column label="操作" width="220px" align="center">
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" circle size="mini" title="编辑" @click="edit(scope.row)"></el-button>
<el-button type="danger" icon="el-icon-delete" circle size="mini" title="注销" @click="del(scope.row)"></el-button>
<el-button type="success" icon="el-icon-refresh-left" circle size="mini" title="恢复" @click="relive(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
<el-dialog title="编辑用户信息" :visible.sync="dialogVisible">
<el-tabs>
<el-tab-pane label="用户信息">
<el-form v-model="editUser">
<el-form-item label="姓名">
<el-input v-model="editUser.name"></el-input>
</el-form-item>
<el-form-item label="性别">
<el-input v-model="editUser.sex"></el-input>
</el-form-item>
<el-form-item label="年龄">
<el-input v-model="editUser.age"></el-input>
</el-form-item>
<el-form-item label="邮箱">
<el-input v-model="editUser.email"></el-input>
</el-form-item>
<!-- <el-date-picker >
<el-input v-model="editUser.end_time" ></el-input>
</el-date-picker> -->
<!-- <el-date-picker label="结束时间" v-model="editUser.end_time" type="datetime" placeholder="选择日期时间"></el-date-picker> -->
</el-form>
</el-tab-pane>
</el-tabs>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="editCommit">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
// import fecha from 'fecha'
// import moment from 'moment'
export default {
name: 'ChangeUser',
data () {
return {
datas: [],
dialogVisible: false,
editUser: {
phone: '',
info: {
name: '',
nick_name: '',
note: ''
}
}
}
},
mounted () {
this.loaddata()
},
methods: {
loaddata () {
this.$http.get('/user/get_user_info/').then(resp => {
this.datas = resp.data
})
},
edit (user) {
if (!user.info) {
user.info = { name: '', nick_name: '', note: '' }
}
this.editUser = user
this.dialogVisible = true
},
editCommit () {
this.$http.post('/user/updata_user/' + this.editUser.id + '/', this.editUser).then(resp => {
if (resp.status === 200) {
this.$message.success('修改成功')
this.loaddata()
} else {
this.$message.error('修改失败')
}
})
this.dialogVisible = false
},
del (row) {
this.$confirm('确认是否删除').then(() => {
this.$http.post('/user/del_user/' + row.id + '/', this.editUser).then(resp => {
if (resp.status === 200) {
this.$message.success('删除成功')
this.loaddata()
} else {
this.$message.error('此用户已删除')
}
}).catch(e => {
this.$message.error('删除失败, 当前用户存在关联数据。')
})
})
},
relive (row) {
this.$confirm('确认恢复').then(() => {
this.$http.post('/user/relive_user/' + row.id + '/', this.editUser).then(resp => {
if (resp.status === 200) {
this.$message.success('恢复成功')
this.loaddata()
} else {
this.$message.error('此用户已恢复')
}
}).catch(e => {
this.$message.error('恢复失败')
})
})
}
}
}
</script>
<style>
.el-table {
width: 100%;
}
.search-container {
height: 50px;
display: flex;
align-items: center;
}
.el-autocomplete {
width: 500px;
}
</style>
可以看到我们用Vue + elementui其实还是遵循三要素,只不过我们的html变成了template模板,里面用的是elem组件。这块感兴趣的朋友可以查看其他人的博客,如何搭建Vue框架,包括路由配置、模板选择,把整个环境搭建好之后我们可以去element官网学习其使用方法,链接如下:Element - The world's most popular Vue UI framework 详细的讲述了从安装到使用的过程,熟悉其原理和逻辑之后基本上就是面向CV编程。
三、重点突破
作为后端开发人员,当然是更加喜欢研究业务逻辑的。分析接口上的一些原理,页面美不美咱也不知道,咱就是能实现功能就行。页面上存在的增删改查等业务逻辑都需要后台接口,那怎么去开发后台接口呢,可以用java也可以用python,两种语言都有框架,例如java的spring MVC、spring boot,python的django、flask等等。有兴趣的朋友可以下去自学一下。今天主要是前台拿到后台给的接口之后怎么去对接好。
路由突破
首先就是引入路由,路由是在route目录下的index.js文件里面配置的,和这里的name名要一直,目的在于找到当前url所属模块,就是通过路由去定位找到的。其次就是判断前台传入字段,把用的到的字段都放在一个字典里,这里我们经常叫做json数据,因为前后端交互的时候就是通过json数据传递的,前台stingify把json数据转成字符串,后台json.dump,json.load的再把字符串形式的json数据转成字典或列表形式。
接口突破
随后重要的点就是我们的方法,可以理解成函数。一般情况下,前端页面做出一些操作之后,会产生逻辑上的变化的这种,我们会将其设置成点击事件、移动事件、拖拽事件等。这里就以点击事件为例子:
<el-button type="primary" icon="el-icon-edit" circle size="mini" title="编辑" @click="edit(scope.row)"></el-button> <el-button type="danger" icon="el-icon-delete" circle size="mini" title="注销" @click="del(scope.row)"></el-button> <el-button type="success" icon="el-icon-refresh-left" circle size="mini" title="恢复" @click="relive(scope.row)"></el-button>
可以看到@click后面跟的我们设计好的方法名字,然后再method里面开始对其进行分装,在封装的过程中,需要用到http,或者https网络协议,对网络感兴趣的可以下去研究一下。确定好网络协议、请求方法、请求路径(后台的接口路由)之后我们就可以安装上述代码进行封装了。
随后我们接收后台响应的数据。resp,可以对响应做一些判断、循环等操作。这个可以根据业务需求而定。
四、总结
总体架构设计就是这样的一个思路,写好一个页面之后其他的都可以举一反三一一列出。设计思路就是:
1、根据需求分析搭建Vue项目框架、模块、路由、配置项、各种插件等
2、设计页面可以参考上述分享的链接进行学习并开发
3、设计样式可以学习一下css的基础知识
4、对接接口:在有接口的前提下,熟悉网络知识、json数据传输知识等
祝愿每一个对计算机感兴趣的朋友都能学有所成。创作不易,记得点赞收藏关注。