配置安装模块如下
npm i vue-router@3
配置main.js文件
import Vue from 'vue'
import App from './App.vue'
import router from "@/router";
import ElementUI from 'element-ui'//导入element-ui
import 'element-ui/lib/theme-chalk/index.css'//导入element-ui的样式文件
import * as echarts from 'echarts'//导入echarts
Vue.prototype.$echarts = echarts//将echarts添加到Vue的原型上
Vue.use(ElementUI)
new Vue({
router,
render: function (h) { return h(App) },
}).$mount('#app')
对axios进行二次封装,配置请求拦截器和响应拦截器
import axios from "axios";
//1.配置基础路径
const axiosInstance = axios.create({
baseURL:'http://localhost:8089',
timeout:5000
})
//2.定义请求拦截器:给所有请求都带上token
axiosInstance.interceptors.request.use((req)=>{
let token = sessionStorage.getItem('Auth')//获取页面存储中的token信息
if(token){//若token存在
req.headers['Auth'] = token
}
return req;
},(err)=>{//出现错误
return Promise.reject(err)
})
//3.响应拦截器,对服务器响应给客户端的数据进行统一的处理
// axiosInstance.interceptors.response.use((res)=>{
// //1.对响应数据进行处理
// let data = res.data
// let code = data.code
// if(code == 200){
// return data
// }else {
// return Promise.reject(data)
// }
//
// },(arr)=>{
// return Promise.reject(arr)
// })
export default axiosInstance
配置router文件夹的index.js文件,路由文件
//路由文件
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter)
//创建路由器对象
const router = new VueRouter({
//路由表
routes:[
{
path:'/book',
name:'book',
component:()=>import('../components/Books')
}
],
mode:'history'
})
export default router
app.vue组件
<template>
<div id="app">
<Container></Container>
</div>
</template>
<script>
import Container from "@/components/Container";
export default {
name: 'App',
components:{
Container,
},
data(){
return{
bookList:[]
}
},
}
</script>
<style>
*{
margin: 0;
padding: 0;
}
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
</style>
Container组件,应用element-ui的布局
<template>
<div>
<el-container>
<el-header height="80px">
<el-row>
<el-col :span="3">
<el-image
style="width: 200px; height: 80px;"
:src="url"
:fit="fit">
</el-image>
</el-col>
</el-row>
</el-header>
<el-container>
<el-aside width="200px" height="500px">
<!-- 导航栏 -->
<el-row class="tac" style="height: 100%" >
<el-col :span="24">
<el-menu
default-active="2"
class="el-menu-vertical-demo"
@open="handleOpen"
@close="handleClose"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b">
<el-submenu index="1">
<template slot="title">
<i class="el-icon-location"></i>
<span>导航一</span>
</template>
<el-menu-item-group>
<template slot="title">分组一</template>
<el-menu-item index="1-1">
<!-- //111111111-->
<router-link to="/book" class="link">图书信息</router-link>
</el-menu-item>
<el-menu-item index="1-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="1-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="1-4">
<template slot="title">选项4</template>
<el-menu-item index="1-4-1">选项1</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">导航二</span>
</el-menu-item>
<el-menu-item index="3" disabled>
<i class="el-icon-document"></i>
<span slot="title">导航三</span>
</el-menu-item>
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span slot="title">导航四</span>
</el-menu-item>
</el-menu>
</el-col>
</el-row>
</el-aside>
<el-main height="500px">
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script>
export default {
name: "Container",
data(){
return{
url:require('../assets/log.jpg'),
fit:'fill'
}
},
methods:{
handleOpen(key, keyPath) {
console.log(key, keyPath);
},
handleClose(key, keyPath) {
console.log(key, keyPath);
}
}
}
</script>
<style scoped>
.tac{
overflow: hidden;
}
.link{
text-decoration: none;
color: rgb(255, 255, 255);
}
.el-header{
background-color: #B3C0D1;
color: #333;
text-align: center;
line-height: 80px;
background-color: rgb(252, 253, 255);
border: 1px solid peachpuff;
}
.el-aside {
background-color: rgb(84, 92, 100) ;
color: #333;
text-align: center;
line-height: 200px;
}
.el-main {
background-color: peachpuff;
color: #333;
text-align: center;
}
</style>
Books.vue组件
<template>
<div>
<el-button type="primary" plain icon="el-icon-plus" @click="openAddDialog">增加图书</el-button>
<el-table :data="tableData" style="width: 100%;" border class="tables">
<el-table-column prop="bookId" label="图书编号" width="200"></el-table-column>
<el-table-column prop="bookName" label="图书名称" width="200"></el-table-column>
<el-table-column prop="publish" label="图书地址" width="200"></el-table-column>
<el-table-column prop="bookAuthor" label="图书作者" width="200"></el-table-column>
<el-table-column prop="imageUrl" label="图书封面" align="center" width="150">
<template slot-scope="scope">
<el-image
style="width:120px; height: 80px; margin-bottom:-4px"
:src="`${scope.row.imageUrl}`"
>
</el-image>
</template>
</el-table-column>
<el-table-column label="操作" width="200">
<!--删除更新按钮-->
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" circle @click="handleEdit(scope.row)"></el-button>
<el-button type="danger" icon="el-icon-delete" circle @click="handleDelete(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[5, 10, 15, 10,25,30]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="bookList.length">
</el-pagination>
<!--对话框-->
<el-dialog
title="提示"
:visible.sync="dialogVisible"
width="30%">
<!-- 表单 -->
<el-form ref="addForm" :model="form" :rules="rulesForm" label-width="80px">
<!-- ref :model用于绑定form,绑定后表单就是一个对象-->
<el-form-item label="图书编号" prop="bookId">
<el-input v-model="form.bookId"></el-input>
</el-form-item>
<el-form-item label="图书名称" prop="bookName">
<el-input v-model="form.bookName" placeholder="请输入图书名称"></el-input>
</el-form-item>
<el-form-item label="图书作者" prop="bookAuthor">
<el-input v-model="form.bookAuthor" placeholder="请输入作者"></el-input>
</el-form-item>
<el-form-item label="发布时间" prop="publish">
<el-input v-model="form.publish"></el-input>
</el-form-item>
<!-- 上传图片 -->
<el-upload
class="upload-demo"
drag
action="#"
:show-file-list="false"
:on-change="handlePreview"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
multiple>
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
</el-form>
<span></span>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="addsBook">确 定</el-button>
</span>
</el-dialog>
<EidetBook :dialogEdit="showEditDialog" :rowData="bookValue" @a="getBooks"/>
</div>
</template>
<script>
import $http from '../axios/index';
import EidetBook from "@/components/EidetBook";
export default {
name: "Books",
components:{
EidetBook
},
data(){
return{
bookList:[],//所有记录数
tableData:[],//分页数据
dialogVisible:false,
showEditDialog:{show:false
},
bookValue:{
},
imageUrl:'',
uploadImage:'',
currentPage:1,//默认当前页是第一页
pageSize:5,//默认每页显示5条记录
form:{
bookName:'',
bookAuthor:'',
bookId:'',
publish:''
},
rulesForm:{//设置表单验证的规则
bookId:[
{required:true,message:'请输入图书名称',trigger:'blur'}
],
bookName:[
{required:true,message:'请输入图书作者',trigger:'blur'}
],
bookAuthor: [
{required:true,message:'请输入出版社',trigger:'blur'}
],
publish:[
{required:true,message:'请输入图书价格',trigger:'blur'}
]
}
}
},
methods:{
//上传图片
//图片上传之前的验证
beforeAvatarUpload(file) {
const isJPG = file.type === 'image/jpeg';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPG) {
this.$message.error('上传头像图片只能是 JPG 格式!');
this.imageUrl = ''
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!');
this.imageUrl = ''
}
return isJPG && isLt2M;
},
//on-change的事件处理函数,显示图片
handlePreview(file){
this.imageUrl = URL.createObjectURL(file.raw)
this.uploadImage = file.raw
},
//on-success事件触发的函数:图片上传成功后
handleAvatarSuccess(res, file) {
this.imageUrl = URL.createObjectURL(file.raw);
},
//删除
handleDelete(row) {
$http.delete('/users/delbooks',{
params:{
bookId:row.bookId
}
}).then(()=>{
this.getBooks()
})
},
//编辑按钮
handleEdit(row){
this.showEditDialog.show = true
this.bookValue = row
},
//打开增加图书的对话框
openAddDialog(){
this.dialogVisible = true
},
//增加图书对话框的确定按钮的验证
addsBook(){
let formDate = new FormData()
formDate.append('bookId',this.form.bookId)
formDate.append('bookName',this.form.bookName)
formDate.append('bookAuthor',this.form.bookAuthor)
formDate.append('publish',this.form.publish)
formDate.append('uploadImage',this.uploadImage)
//$refs['form表单里面ref属性的值']
this.$refs['addForm'].validate((valid)=>{
if(valid){//验证通过
//1.向服务器发起请求
$http.post('/users/addBook',formDate).then(res=>{
this.getBooks()
//2.获取服务器的相应数据,操作成功要更新表格的数据
if(res.data.code == 200){
//弹出对话框
//3.重置对话框中的表单,关闭对话框
this.$refs['addForm'].resetFields()//重置会话框中的表单
//4.弹出消息框
this.dialogVisible = false//关闭对话框
this.$message({
showClose:true,
message:'添加成功',
type:"success",
duration:2000
})
}
})
}else {//验证未通过
alert('验证未通过')
//不能向服务器发起请求,返回false
}
})
},
//全局查找,刷新表格
getBooks(){
$http.get('/users/all').then(res=>{
this.bookList = res.data.data
this.getPageData()//获取分页数据
}).catch(e=>{
console.log(e)
})
},
// 分页
//每页显示的记录数发生改变时
handleSizeChange(val){
this.pageSize = val
console.log('每页显示的记录数',this.pageSize);
this.getPageData()
},
// 当前的页码发生改变时
handleCurrentChange(val){
this.currentPage = val
console.log('当前的页码',this.currentPage);
this.getPageData()
},
// 获取分页函数的代码
getPageData(){
//计算分页数据的起始位置
let start = (this,this.currentPage - 1)*this.pageSize
//计算分页数据的结束位置
let end = start + this.pageSize
// 获取分页数据
this.tableData = this.bookList.slice(start,end)
}
},
created() {
this.getBooks()
}
}
</script>
<style scoped>
.tables{
text-align: center;
}
.upload-demo .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.upload-demo .el-upload:hover {
border-color: #409EFF;
}
.el-icon-upload {
font-size: 28px;
color: #8c939d;
width: 100px;
height: 70px;
line-height: 70px;
text-align: center;
}
</style>
Eidet.vue组件,信息的更新
<template>
<div>
<el-dialog
title="修改图书"
:visible.sync="dialogEdit.show"
width="30%">
<!-- 表单 -->
<el-form ref="addForm" :model="rowData" :rules="rulesForm" label-width="80px">
<!-- ref :model用于绑定form,绑定后表单就是一个对象-->
<el-form-item label="图书编号" prop="bookId">
<el-input v-model="rowData.bookId" disabled></el-input>
</el-form-item>
<el-form-item label="图书名称" prop="bookName">
<el-input v-model="rowData.bookName" placeholder="请输入图书名称"></el-input>
</el-form-item>
<el-form-item label="图书作者" prop="bookAuthor">
<el-input v-model="rowData.bookAuthor" placeholder="请输入作者"></el-input>
</el-form-item>
<el-form-item label="发布时间" prop="publish">
<el-input v-model="rowData.publish"></el-input>
</el-form-item>
</el-form>
<span></span>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogEdit.show = false">取 消</el-button>
<el-button type="primary" @click="EditBook">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import $http from '../axios/index';
export default {
name: "EidetBook",
props:{
dialogEdit:{ type:Object },
rowData:{ type:Object }
},
data(){
return{
form:this.rowData,
rulesForm:{//设置表单验证的规则
bookId:[
{required:true,message:'请输入图书名称',trigger:'blur'}
],
bookName:[
{required:true,message:'请输入图书作者',trigger:'blur'}
],
bookAuthor: [
{required:true,message:'请输入出版社',trigger:'blur'}
],
publish:[
{required:true,message:'请输入图书价格',trigger:'blur'}
]
}
}
},
methods:{
EditBook(){
this.$refs['addForm'].validate((valid)=>{
if(valid) {
$http.post('/users/editbook', {
bookId :this.rowData.bookId,
bookName:this.rowData.bookName,
bookAuthor:this.rowData.bookAuthor,
publish:this.rowData.publish
}).then(res=>{
this.dialogEdit.show = false
if (res.data.code === 200) {
this.$message({
showClose: true,
message: '编辑成功!',
type: 'success'
});
}
this.getBooks()
this.$emit('a',this.EditBook)
}).catch(e => {
console.log(e);
})
}
})
}
}
}
</script>
<style scoped>
</style>