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>
至此,整个学生列表组件写完了。