**该篇文章展示前端代码**
**Mysql+MybatisPlus+Springboot+Shiro+Swagger+Element**
前端开发环境
node.js
hbuilder
图书管理借阅前端所含模块的功能
1.图书借阅图书类别
2.图书借阅馆藏图书
3.借阅用户
4.借阅模块
5.借阅日志
6.借阅数据分析
对应的vue文件组成
<!-- 模板区:编写UI标签,切记该标签中只能有一个根标签,单文件规定的、否则报错 -->
<template>
</template>
<!-- 行为区,编写的是和后端进行交互的js代码,vue代码 -->
<script>
export default {
data() { //对象定义属性区
return {
}
},
methods: { //用户自定义方法区
},
created() { //生命周期函数、浏览器渲染时执行该函数代码
}
}
</script>
<!-- 样式区--
<style scoped>
</style>
对应控制前端页面的设置和一些检错机制
<template>
<el-card class="box-card">
<div slot="header" class="header-card">
<span>图书借阅管理系统</span>
</div>
<el-form :model="user" :rules="rules" ref="user">
<el-form-item prop="username">
<el-input suffix-icon="el-icon-user-solid" v-model="user.username" clearable placeholder="请输入用户名称"></el-input>
</el-form-item>
<el-form-item prop="password">
<el-input suffix-icon="el-icon-s-goods" v-model="user.password" clearable type="password" placeholder="请输入密码">
</el-input>
</el-form-item>
<el-button type="success" plain @click="login">登录</el-button>
</el-form>
</el-card>
</template>
<script>
export default {
data() {
return {
rules: {
username: [{
required: true,
message: '请输入用户名称',
trigger: 'blur'
}],
password: [{
required: true,
message: '请输入密码',
trigger: 'blur'
}
],
},
user: {
username: '',
password: ''
}
}
},
methods: {
login() {
this.$refs['user'].validate((valid) => {
if (valid) {
this.$http.get('http://localhost/user/login',{
params:this.user
})
.then(res=>{
if(res.data.data==null){
this.$message.error('你输入的用户名称或者密码不正确,或者账号被锁定,请联系管理员');
}else{
sessionStorage.setItem("username",res.data.data)
this.$router.push('/welcome');
}
})
.catch(e=>{
this.$message.error('错了哦,网络异常');
})
}
});
}
}
}
</script>
<style scoped>
.box-card {
width: 550px;
height: 280px;
border-radius: 10px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
box-shadow: 10px 20px 30px #888888;
}
.login-form {
position: absolute;
bottom: 0px;
width: 100%;
padding: 0px 20px;
box-sizing: border-box;
}
.el-button {
display: flex;
justify-content: center;
width: 100%;
font-weight: bold;
height: 40px;
font-size: 18px;
border-radius: 10px;
}
.header-card {
display: flex;
justify-content: center;
font-size: 18px;
}
.el-input {
border-radius: 10px;
height: 50px;
font-size: 18px;
border-bottom-color: green;
}
</style>
对应的是常规的设置 此处的图展示的借阅数据 用到了Eacharts
<template>
<el-row :gutter="10">
<div id="main" style="width: auto;height:250px;"></div>
<div id="main2" style="width: auto;height:350px;"></div>
</el-row>
</template>
<script>
export default {
data() {
return {
xdata: [],
ydata: [],
data: [],
list: []
}
},
methods: {
showEcharts() {
this.$http.get('http://localhost/borrow/getBorrowCounter')
.then(res => {
var array = res.data.data;
for (var i in array) {
this.xdata.push(array[i].bname);
this.ydata.push(array[i].counter);
}
var myEcharts2 = this.$echarts.init(document.getElementById("main2"));
myEcharts2.setOption({
xAxis: {
axisLabel: {
interval: 0,
rotate: 10
},
type: 'category',
data: this.xdata
},
yAxis: {
type: 'value'
},
series: [{
data: this.ydata,
type: 'bar',
showBackground: true,
backgroundStyle: {
color: 'rgba(220, 220, 220, 0.8)'
},
itemStyle: {
color: "rgba(140, 41, 115, 0.58)"
}
}]
})
})
.catch(e => {
this.$message.error('错了,中国');
})
},
showRose() {
this.$http.get('http://localhost/category/getCateBook')
.then(res => {
console.info(res);
this.list = res.data.data;
console.info(this.list);
this.list.forEach(item => {
console.info(item);
var obj = {
name: item['catename'],
value: item['counter']
}
console.info(obj);
console.info(this.data);
this.data.push(obj);
console.info(this.data);
})
var myEcharts = this.$echarts.init(document.getElementById("main"));
myEcharts.setOption({
series: [{
type: 'pie',
data: this.data,
roseType:'area'
}]
})
}).catch(e => {})
}
},
created() {
this.showEcharts();
this.showRose();
}
}
</script>
<style>
</style>
主要实现了 CURD 且进行数据添加和修改的特殊判断 (比如对空值的传递)
<!-- 该标签主要编写前端网页代码,网页标签在template模板中只能有一个根标签 -->
<template>
<!-- 定义的卡片组件 -->
<el-card class="box-card">
<div slot="header" class="clearfix">
<!-- 面包屑组件 -->
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/welcome' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>图类别管理</el-breadcrumb-item>
<el-breadcrumb-item>图书类别信息管理</el-breadcrumb-item>
</el-breadcrumb>
</div>
<!-- elrow组件的布局 gutter 间隔距离 -->
<el-row :gutter="20">
<el-col :span="6">
<el-input v-model="cname" clearable @clear="findPager" placeholder="请输入要查询的名称"></el-input>
</el-col>
<el-col :span="6">
<el-button type="primary" @click="findPager" icon="el-icon-search">查询</el-button>
<el-button type="success" @click="addDialog()" icon="el-icon-plus">添加</el-button>
</el-col>
</el-row>
<!-- 定义表格组件 表格组件中过多:data属性绑定数据 数据是一个数组-->
<el-table :data="tableData">
<el-table-column prop="catename" label="图书类别名称"></el-table-column>
<el-table-column label="操作">
<!-- 作用域插槽 -->
<template slot-scope="scope">
<!-- {{}}输出数据 加入组件 -->
<!-- {{scope.row}} -->
<el-tooltip content="修改" placement="left">
<el-button type="warning" @click=editDialog(scope.row) circle icon="el-icon-edit"></el-button>
</el-tooltip>
<el-tooltip content="删除" placement="right">
<el-button type="danger" @click="remove(scope)" circle icon="el-icon-delete"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pager.page"
:page-sizes="[5, 15, 20, 25]"
:page-size="pager.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="pager.total">
</el-pagination>
<!-- 定义添加对话框 -->
<el-dialog title="添加类别信息" :visible.sync="addDialogFlag">
<el-form :model="category" :rules="rules" ref="category">
<el-form-item prop="catename">
<el-input v-model="category.catename" placeholder="请输入图书类别名称"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="addDialogFlag =false">取消</el-button>
<el-button type="primary" @click="save">保存</el-button>
</div>
</el-dialog>
// 对应的选出框
<el-dialog title="修改类别信息" :visible.sync="editDialogFlag">
<el-form :model="category" :rules="rules" ref="category">
<el-form-item prop="catename">
<el-input v-model="category.catename" placeholder="请输入图书类别名称"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="editDialogFlag =false">取消</el-button>
<el-button type="primary" @click="update">修改</el-button>
</div>
</el-dialog>
</el-card>
</template>
<!-- 行为区,编写的是和后端进行交互的js代码,vue代码 -->
<script>
export default {
data() { //该属性中放置用户定义的变量,类似与类的属性定义
return {
rules:{ // 定义添加表单验证规则
catename:[{
required: true,
message: '请输入图书类别名称',
trigger: 'blur'
}]
},
addDialogFlag:false, // 显示对话框 标记 默认是不显示
editDialogFlag:false,
cname:'',
tableData:[] ,// 定义表格的数组 初始化表格数据
pager:{ // 封装分页对象
page:1, // 分页起始数据
limit:5, // 分页显示最大条数
total:0 // 统计记录数字
},
category:{ // 定义对象 封装添加或者修改的数据
cateis:0,
catename:''
}
}
},
methods: {
update(){
this.$refs['category'].validate(valid=>{
if(valid){
this.$http.post('http://localhost/category/update',this.category)
.then(res=>{
if(res.data.code==200){
this.$message({
showClose: true,
message: res.data.message,
type: 'success'
});
this.editDialogFlag=!this.editDialogFlag // 关闭对话框
this.findPager(); // 再次调用查询
}
}).cath(err=>{
this.$message.error('错了 有问题')
})
}
})
},
// 用户自定义
save(){
this.$refs['category'].validate(valid=>{
if(valid){
this.$http.post('http://localhost/category/save',this.category)
.then(res=>{
if(res.data.code==200){
this.$message({
showClose: true,
message: res.data.message, // 获取返回对应的信息
type: 'success'
});
this.addDialogFlag=!this.addDialogFlag // 关闭对话框
this.findPager(); // 再次调用查询
}
}).cath(err=>{
this.$message.error('错了 有问题')
})
}
})
},
editDialog(row){ // 点击改方法 是打开修改对话框 并不是保存
this.category=row; // 传入对应的参数
this.editDialogFlag=!this.editDialogFlag;
},
addDialog(){
this.addDialogFlag=!this.addDialogFlag;
},
//该标签中编写的是用户自定义的javascript方法
// 定义方法 初始化表格中的数据 请求 ajax axios
remove(scope){
this.$http.post('http://localhost/category/remove?cateid='+scope.row.cateid)
.then(res=>{
if(res.data.code==200){
this.$message({
message: res.data.message,
type: 'success'
});
this.findPager();
}
})
},
handleSizeChange(val){
console.log('每页$(val)条');
this.pager.limit=val;
this.findPager();
},
handleCurrentChange(val){
console.log('每页$(val)条');
this.pager.page=val;
this.findPager();
},
findPager(){
this.$http.get('http://localhost/category/findPager',{
params:{
page:this.pager.page,
limit:this.pager.limit,
cname:this.cname
}
}).then(res=>{
console.info(res);
this.tableData=res.data.data.data;
this.pager.total=res.data.data.count;
})
}
},
created() { //vue技术的生命周期 浏览器在加载当前页面 渲染数据
this.findPager();
}
}
</script>
<!-- 标签放置的样式CSS -->
<style scoped>
.el-pagination {
margin-top: 10px;
}
.el-breadcrumb {
margin-bottom: 20px;
}
</style>
还是常规的CRUD 以及表单添加和修改的非法值 进行拦截判断
对应的难点 对用户是否可以正常使用的状态 进行转台的改变的监听 设置一个标记值 进行对应的改变
<!-- 该标签主要编写前端网页代码,网页标签在template模板中只能有一个根标签 -->
<template>
<!-- 定义的卡片组件 -->
<el-card class="box-card">
<div slot="header" class="clearfix">
<!-- 面包屑组件 -->
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/welcome' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>系统信息管理</el-breadcrumb-item>
<el-breadcrumb-item>用户信息管理</el-breadcrumb-item>
</el-breadcrumb>
</div>
<!-- elrow组件的布局 gutter 间隔距离 -->
<el-row :gutter="20">
<el-col :span="6">
<el-input v-model="uname" clearable @clear="findPager" placeholder="请输入用户查询的名称"></el-input>
</el-col>
<el-col :span="6">
<el-button type="primary" @click="findPager" icon="el-icon-search">查询</el-button>
<el-button type="success" @click="addDialog()" icon="el-icon-plus">添加</el-button>
</el-col>
</el-row>
<!-- 定义表格组件 表格组件中过多:data属性绑定数据 数据是一个数组-->
<el-table :data="tableData" style="width:100%">
<el-table-column prop="uname" label="用户名称"></el-table-column>
<el-table-column prop="password" label="密码"></el-table-column>
<el-table-column prop="images" label="头像">
<<template slot-scope="scope">
<img :src="scope.row.images" style="width:40px; height:40px;"/>
</template>
</el-table-column>
<el-table-column prop="stats" label="状态">
<template slot-scope="scope">
<el-switch
v-model="scope.row.stats"
:active-value="0"
:inactive-value="1"
active-color="#13ce66"
inactive-color="#ff4949"
@change="changeStats(scope.row)">
</el-switch>
</template>
</el-table-column>
<el-table-column label="操作">
<!-- 作用域插槽 -->
<template slot-scope="scope">
<!-- {{}}输出数据 加入组件 -->
<!-- {{scope.row}} -->
<el-tooltip content="修改" placement="left">
<el-button type="warning" @click=editDialog(scope.row) circle icon="el-icon-edit"></el-button>
</el-tooltip>
<el-tooltip content="删除" placement="right">
<el-button type="danger" @click="remove(scope)" circle icon="el-icon-delete"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pager.page"
:page-sizes="[5, 15, 20, 25]"
:page-size="pager.limit"
layout="total, sizes, prev, pager, next, jumper"
:total="pager.total">
</el-pagination>
<!-- 定义添加对话框 -->
<el-dialog title="添加用户信息" :visible.sync="addDialogFlag">
<el-form :model="user" :rules="rules" ref="user">
<el-form-item prop="uname">
<el-input v-model="user.uname" placeholder="请输入用户名称"></el-input>
</el-form-item>
<el-form-item prop=password>
<el-input v-model="user.password" placeholder="请输入用户密码"></el-input>
</el-form-item>
<el-form-item prop="imagqs">
<el-input v-model="user.images" placeholder="请输入图像"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="addDialogFlag =false">取消</el-button>
<el-button type="primary" @click="save">保存</el-button>
</div>
</el-dialog>
// 对应的选出框
<el-dialog title="修改类别信息" :visible.sync="editDialogFlag">
<el-form :model="user" :rules="rules" ref="user">
<el-form-item prop="uname">
<el-input v-model="user.uname" placeholder="请输入用户名称"></el-input>
</el-form-item>
<el-form-item prop=password>
<el-input v-model="user.password" placeholder="请输入用户密码"></el-input>
</el-form-item>
<el-form-item prop="imagqs">
<el-input v-model="user.images" placeholder="请输入图像"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="reset">取消</el-button>
<el-button type="primary" @click="update">修改</el-button>
</div>
</el-dialog>
</el-card>
</template>
<!-- 行为区,编写的是和后端进行交互的js代码,vue代码 -->
<script>
export default {
data() { //该属性中放置用户定义的变量,类似与类的属性定义
return {
addDialogFlag:false, // 显示对话框 标记 默认是不显示
editDialogFlag:false,
cname:'',
tableData:[] ,// 定义表格的数组 初始化表格数据
pager:{ // 封装分页对象
page:1, // 分页起始数据
limit:5, // 分页显示最大条数
total:0 // 统计记录数字
},
category:{ // 定义对象 封装添加对象
cateis:0,
catename:''
},
rules:{
uname:[{
required: true,
message: '请输入用户名称',
trigger: 'blur'
}],
password:[{
required: true,
message: '请输入密码',
trigger: 'blur'
}],
images:[{
required: true,
message: '请选择头像',
trigger: 'blur'
}]
},
user: { //定义用户对象 主要封装传递的数据 更改用户状态 修改或者添加用户信息
uid: 0,
uname: '',
password: '',
images: '',
stats: ''
},
uname: ''
// pager: { //封装的分页参数
// page: 1, //分页起始数据
// limit: 5, //每页显示最大条数
// total: 0 //统计分页记录数
// },
//定义条件查询接收值的变量
// tableData: [] //定义表格中填充的数据,该数据要从后端服务中获取
}
},
methods: {
changeStats(row){
this.user=row; //用户定义的user对象赋值
this.$http.post('http://localhost/user/changeStats',this.user)
.then(res=>{
if(res.data.data.code==200){
this.$message({
message:res.data.message,
type:'success'
});
this.findPager();
}
}).catch(err=>{
this.$message.error('错了哦, 网络异常')
})
},
update(){
this.$refs['user'].validate(valid=>{
if(valid){
this.$http.post('http://localhost/user/update',this.user)
.then(res=>{
if(res.data.code==200){
this.$message({
showClose: true,
message: res.data.message,
type: 'success'
})
this.editDialogFlag=!this.editDialogFlag // 关闭对话框
this.findPager(); // 再次调用查询
}
}).cath(err=>{
this.$message.error('错了 有问题')
})
}
})
},
// 避免出现对应的 修改之后取消 之后再次添加依然对值进行填充
rest(){
this.user={};
this.editDialogFlag=!this.editDialogFlag;
},
// 用户自定义
save(){
this.$refs['user'].validate(valid=>{
if(valid){
this.$http.post('http://localhost/user/save',this.user)
.then(res=>{
if(res.data.code==200){
this.$message({
showClose: true,
message: res.data.message, // 获取返回对应的信息
type: 'success'
});
this.addDialogFlag=!this.addDialogFlag // 关闭对话框
this.findPager(); // 再次调用查询
}
}).cath(err=>{
this.$message.error('错了 有问题')
})
}
})
},
// 进行数据的填充
editDialog(row){ // 点击改方法 是打开修改对话框 并不是保存
this.user=row; // 传入对应的参数
this.editDialogFlag=!this.editDialogFlag;
},
addDialog(){
this.addDialogFlag=!this.addDialogFlag;
},
//该标签中编写的是用户自定义的javascript方法
// 定义方法 初始化表格中的数据 请求 ajax axios
remove(scope){
this.$http.post('http://localhost/user/remove?uid='+scope.row.uid)
.then(res=>{
if(res.data.code==200){
this.$message({
message: res.data.message,
type: 'success'
});
this.findPager();
}
})
},
handleSizeChange(val){
console.log('每页$(val)条');
this.pager.limit=val;
this.findPager();
},
handleCurrentChange(val){
console.log('每页$(val)条');
this.pager.page=val;
this.findPager();
},
findPager(){
this.$http.get('http://localhost/user/findPager',{
params:{
page:this.pager.page,
limit:this.pager.limit,
uname:this.uname
}
}).then(res=>{
console.info(res);
this.tableData=res.data.data.data;
this.pager.total=res.data.data.count;
})
}
},
created() { //vue技术的生命周期 浏览器在加载当前页面 渲染数据
this.findPager();
}
}
</script>
<!-- 标签放置的样式CSS -->
<style scoped>
.el-pagination {
margin-top: 10px;
}
.el-breadcrumb {
margin-bottom: 20px;
}
</style>
剩下的整体逻辑都是一样的 围绕CRUD 不再进行展示源码 喜欢私信提供源码