本文为博主的vue实战小项目系列中的第五篇,很适合后端或者才入门的小伙伴看,一个前端项目从0到1的保姆级教学。前面的内容:
【vue实战项目】通用管理系统:登录页-CSDN博客
【vue实战项目】通用管理系统:封装token操作和网络请求-CSDN博客
【vue实战项目】通用管理系统:api封装、404页-CSDN博客
【vue实战项目】通用管理系统:首页-CSDN博客
目录
1.概述
2.列表
3.分页
4.删除
5.查询
1.概述
本文实现的是学生管理界面里面的学生列表组件,该组件内包含对学生信息的查询、删除、以及对数据的分页。没有录入功能,录入功能在接下来后续的信息管理组件中。
首先来看一下学生列表组件的最终页面效果:
2.列表
学生列表studentList组件是个表格,表格在elementUI上面去找一个即可,然后调整一下.
代码:
<template>
<div>
<el-table :data="tableData" border style="width: 100%">
<el-table-column prop="date" label="日期" width="180"> </el-table-column>
<el-table-column prop="name" label="姓名" width="180"> </el-table-column>
<el-table-column prop="address" label="地址"> </el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1516 弄'
}]
}
}
}
</script>
效果:
封装api:
根据之前的编码规范,这里我们依然将获取数据的方法封装到api(api.js)中。
import service from '../utils/service'
export function login(data){
return service({
method:'post',
url:'/login',
data
})
}
export function students(params){
return service({
method:'get',
url:'/student/list',
params
})
}
在sutudentList中调用api获取数据:
<script>
import {students} from '@/api/api.js'
export default {
data() {
return {
tableData: []
}
},
methods:{
getData(params){
students(params).then((res)=>{
console.log(res);
})
}
},
created(){
this.getData();
}
}
</script>
可以看到获取到了所有数据:
既然能获取到数据,接下来绑定数据即可:
<template>
<div>
<el-table :data="tableData" border style="width: 100%">
<el-table-column prop="name" label="姓名" align="center"> </el-table-column>
<el-table-column prop="age" label="年龄" align="center"> </el-table-column>
<el-table-column prop="sex" label="性别" align="center"> </el-table-column>
<el-table-column prop="classNum" label="班级" align="center"> </el-table-column>
<el-table-column prop="number" label="学号" align="center"> </el-table-column>
<el-table-column prop="address" label="地址" align="center"> </el-table-column>
<el-table-column prop="state" label="状态" align="center"> </el-table-column>
<el-table-column label="操作">
<template>
<el-button type="danger" size="mini" icon="el-icon-delete"></el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import {students} from '@/api/api.js'
export default {
data() {
return {
tableData: []
}
},
methods:{
getData(params){
students(params).then((res)=>{
if(res.status===200){
this.tableData=res.data
}
})
}
},
created(){
this.getData();
}
}
</script>
最终效果:
这里有个小地方需要注意,就是关于数据转换。后端传回来的数据中状态和类型字段都是用数字表示的。需要在前端做对应转换:
可以这样做:
export default {
data() {
return {
tableData: []
}
},
methods:{
getData(params){
students(params).then((res)=>{
if(res.status===200){
this.tableData=res.data
this.tableData.forEach(item=>{
item.sex===1?item.sex='男':item.sex='女'
})
}
})
}
},
created(){
this.getData();
}
}
但是上面这样做会有一个问题:
因为这里把值取成了中文,再传给后端的时候就会是中文,后端还要做一次转换,搞得很麻烦。
巧妙一点,再加一个字段来存中文就是。其它状态字段类似处理。
<script>
import {students} from '@/api/api.js'
export default {
data() {
return {
tableData: []
}
},
methods:{
getData(params){
students(params).then((res)=>{
if(res.status===200){
this.tableData=res.data
this.tableData.forEach(item=>{
item.sex===1?item.sex_text='男':item.sex_text='女'
item.status===1?item.status_text='已入学':item.status_text='未入学'
})
}
})
}
},
created(){
this.getData();
}
}
</script>
3.分页
elementUI提供了完整的分页组件。还是老规矩去官网上看一款,拿来就用。
把分页组件放到studentList组件中去:
<template>
<div class="studentList">
<el-table :data="tableData" border style="width: 100%">
<el-table-column prop="name" label="姓名" align="center">
</el-table-column>
<el-table-column prop="age" label="年龄" align="center">
</el-table-column>
<el-table-column prop="sex_text" label="性别" align="center">
</el-table-column>
<el-table-column prop="classNum" label="班级" align="center">
</el-table-column>
<el-table-column prop="number" label="学号" align="center">
</el-table-column>
<el-table-column prop="address" label="地址" align="center">
</el-table-column>
<el-table-column prop="status_text" label="状态" align="center">
</el-table-column>
<el-table-column label="操作">
<template>
<el-button
type="danger"
size="mini"
icon="el-icon-delete"
></el-button>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<div class="block">
<span class="demonstration">完整功能</span>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="1"
:page-sizes="[5,10,15,20]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
>
</el-pagination>
</div>
</div>
</template>
<script>
import { students } from "@/api/api.js";
export default {
data() {
return {
tableData: [],
currentPage:1, //当前页数
pageSize:10, //每页显示条数
total:0 //总条数
};
},
methods: {
getData(params) {
students(params).then((res) => {
if (res.data.code === 200) {
this.tableData = res.data.data;
this.total=res.data.total;
this.tableData.forEach((item) => {
item.sex === 1 ? (item.sex_text = "男") : (item.sex_text = "女");
item.status === 1
? (item.status_text = "已入学")
: (item.status_text = "未入学");
});
}
});
},
//分页方法
handleSizeChange(val) {
console.log(`每页 ${val} 条`);
},
handleCurrentChange(val) {
console.log(`当前页: ${val}`);
},
},
created() {
this.getData();
},
};
</script>
<style lang="less">
.studentList{
.el-pagination{
text-align: left;
margin-top: 20px;
}
}
</style>
接下来就是分页中关键的步骤了,有关分页逻辑的编写。
首先是分页的总页数:
操作组件自带的方法即可控制切换pageSize的时候,分页插件自动变换总页数。这两个方法见名知意。
handleSizeChange(val) {
this.pageSize=val;
this.currentPage=1;
},
handleCurrentChange(val) {
this,this.currentPage=val;
},
控制数据条数的显示:
el-table的:data是用来给列表组件绑定数据的,我们就是通过所绑定的这个数组来控制数据的显示的。js里面调用数组的slice(index,size)可以对数组进行切片,这里我们就用这个方法来实现。
<!--slice((当前页数-1)*每页条数,当前页数*当前条数)-->
<el-table :data="tableData.slice((currentPage-1)*pageSize,currentPage*pageSize)" border style="width: 100%">
最后可以用计算属性来封装一下分页的方法,最后的页面代码:
<template>
<div class="studentList">
<!--slice((当前页数-1)*每页条数,当前页数*当前条数)-->
<el-table :data="compData" border style="width: 100%">
<el-table-column prop="name" label="姓名" align="center">
</el-table-column>
<el-table-column prop="age" label="年龄" align="center">
</el-table-column>
<el-table-column prop="sex_text" label="性别" align="center">
</el-table-column>
<el-table-column prop="classNum" label="班级" align="center">
</el-table-column>
<el-table-column prop="number" label="学号" align="center">
</el-table-column>
<el-table-column prop="address" label="地址" align="center">
</el-table-column>
<el-table-column prop="status_text" label="状态" align="center">
</el-table-column>
<el-table-column label="操作">
<template>
<el-button
type="danger"
size="mini"
icon="el-icon-delete"
></el-button>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<div class="block">
<span class="demonstration">完整功能</span>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[5,10,15,20]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
>
</el-pagination>
</div>
</div>
</template>
<script>
import { students } from "@/api/api.js";
export default {
data() {
return {
tableData: [],
currentPage:1, //当前页数
pageSize:10, //每页显示条数
total:0 //总条数
};
},
methods: {
getData(params) {
students(params).then((res) => {
if (res.data.code === 200) {
this.tableData = res.data.data;
this.total=res.data.total;
this.tableData.forEach((item) => {
item.sex === 1 ? (item.sex_text = "男") : (item.sex_text = "女");
item.status === 1
? (item.status_text = "已入学")
: (item.status_text = "未入学");
});
}
});
},
//分页方法
handleSizeChange(val) {
this.pageSize=val;
this.currentPage=1;
},
handleCurrentChange(val) {
this,this.currentPage=val;
},
},
created() {
this.getData();
},
computed:{
compData(){
return this.tableData.slice((this.currentPage-1)*this.pageSize,this.currentPage*this.pageSize)
}
}
};
</script>
<style lang="less">
.studentList{
.el-pagination{
text-align: left;
margin-top: 20px;
}
}
</style>
效果:
4.删除
删除的话无非就是点击删除按钮,将要删除的行数据的id传给后端。这里的关键是怎么获取到所点击的行的数据,用slot-scope。先写一个删除逻辑,里面不做删除,而是打印这一行的数据。
<el-table-column label="操作">
<template slot-scope="scope">
<el-button
@click="del(scope.row)"
type="danger"
size="mini"
icon="el-icon-delete"
></el-button>
</template>
</el-table-column>
//删除
del(row){
console.log(row);
}
点击删除,可以看到打印出来了该行的数据:
既然都拿到数据了,就真刀真枪的删除即可。
在真刀真枪的删除之前,我们还是依然保持代码风格的整洁,按照前面一样,在api.js里封装一下删除学生的api:
export function studentDel(id){
return service({
method: 'delete',
url:`/student/${id}`
})
}
封装好后去studentList里调用一下:
import{studentDel} from "@/api/api.js"
del(row){
studentDel(row.id).then(res=>{
if(res.data.code===200){
this.$message({message:'删除数据成功',type:'success'})
//删除后要刷新数据
this.getDate()
}
});
}
至此删除功能写完了,可以试试是不是能正常使用。
5.查询
老规矩先去elementUI上面找一个搜索框,没有直接的搜索框,用这个行内表单来改造一下:
其实具体的查询方法和重置方法都不需要重新封装api,可以直接调用getData方法,通过传参的不同来实现,这里直接给出整个组件页面最后的代码:
<template>
<div class="studentList">
<!--查询表单-->
<el-form :inline="true" :model="formInline" class="demo-form-inline" size="mini">
<el-form-item label="姓名">
<el-input v-model="formInline.name" placeholder="请输入姓名"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-button type="primary" @click="reset">查询</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="find">查询</el-button>
</el-form-item>
</el-form>
<el-table :data="compData" border style="width: 100%">
<el-table-column prop="name" label="姓名" align="center">
</el-table-column>
<el-table-column prop="age" label="年龄" align="center">
</el-table-column>
<el-table-column prop="sex_text" label="性别" align="center">
</el-table-column>
<el-table-column prop="classNum" label="班级" align="center">
</el-table-column>
<el-table-column prop="number" label="学号" align="center">
</el-table-column>
<el-table-column prop="address" label="地址" align="center">
</el-table-column>
<el-table-column prop="status_text" label="状态" align="center">
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button
@click="del(scope.row)"
type="danger"
size="mini"
icon="el-icon-delete"
></el-button>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<div class="block">
<span class="demonstration">完整功能</span>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[5, 10, 15, 20]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
>
</el-pagination>
</div>
</div>
</template>
<script>
import { students } from "@/api/api.js";
import { studentDel } from "@/api/api.js";
export default {
data() {
return {
tableData: [],
currentPage: 1, //当前页数
pageSize: 10, //每页显示条数
total: 0, //总条数
formInline:{
name:''
}
};
},
methods: {
getData(params) {
students(params).then((res) => {
if (res.data.code === 200) {
this.tableData = res.data.data;
this.total = res.data.total;
this.tableData.forEach((item) => {
item.sex === 1 ? (item.sex_text = "男") : (item.sex_text = "女");
item.status === 1
? (item.status_text = "已入学")
: (item.status_text = "未入学");
});
}
});
},
//分页方法
handleSizeChange(val) {
this.pageSize = val;
this.currentPage = 1;
},
handleCurrentChange(val) {
this, (this.currentPage = val);
},
//删除
del(row) {
studentDel(row.id).then((res) => {
if (res.data.code === 200) {
this.$message({ message: "删除数据成功", type: "success" });
this.getData();
}
});
},
//查询
find(){
this.getData(this.formInline.name);
},
//重置
reset(){
this.getData();
}
},
created() {
this.getData();
},
computed: {
compData() {
return this.tableData.slice(
(this.currentPage - 1) * this.pageSize,
this.currentPage * this.pageSize
);
},
},
};
</script>
<style lang="less">
.studentList {
.el-form-inline .el-form-item{
text-align: left;
}
.el-pagination {
text-align: left;
margin-top: 20px;
}
}
</style>
至此,整个学生列表组件写完了。