OK,兄弟们!
测试上传图片的后端接口
测试分页条件查询后端接口
测试根据id查询后端接口
测试新增一本书的后端接口
测试修改一本书的后端接口
文章来源:https://www.toymoban.com/news/detail-478274.html
之前写好的后端接口,用postman测试一下,没有问题的话我们就试试开发前端。
准备工作:
用vue创建一个文件,安装VUE步骤我这里引用一下其他人的csdn
(3条消息) Vue脚手架搭建及vue项目创建【详细教程】_星河梦~的博客-CSDN博客https://blog.csdn.net/weixin_53186633/article/details/122461313现在桌面创建一个空的文件夹,然后选择用vscode打开,然后打开终端。
然后在终端输入vue命令新建一个vue项目
vue create book-fornt
然后选择Manually select features,这里我们选下面这5个。按空格和上下箭头选择,选好回车就行
然后这里我们选3.x
下面按这个选择配置就行,选好最后回车就开始创建了
创建好就是这个样子
我们在终端上切到book-fornt项目
cd book-fornt
我们还需要安装axios和element-plus(3.x的饿了么组件交plus)
axios
npm install axios --save
element-plus
npm install element-plus --save
然后在main.js中引入一下
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
createApp(App).use(store).use(router).use(ElementPlus).mount('#app')
修改一下vue.config.js文件里的内容
const { defineConfig } = require('@vue/cli-service')
module.exports = {
devServer:{
port:8020, // 启动端口号
open:true // 启动后是否自动打开网页
}
}
npm run serve跑一下试试,看看项目能不能运行。
都没问题的话我们才能开始开发前端内容。
开发步骤:
先封装前端请求request.js文件
在src目录下新建一个utils文件夹,然后创建一个request.js来封装axios请求
request.js,再上一篇内容里我们的后端接口是
import axios from 'axios'
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项,表示请求URL公共部分
baseURL: 'http://localhost:8785',
// 超时
timeout: 10000
})
//第三步 创建拦截器 http request 拦截器
service.interceptors.request.use(
config => {
//debugger
return config
},
err => {
return Promise.reject(err);
})
// http response 拦截器
service.interceptors.response.use(
response => {
// //debugger
// if (response.data) {
// clearLoginInfo()
// router.push({ name: 'login' })
// } else {
// return response;
// }
return response;
},error => {
return Promise.reject(error.response) // 返回接口返回的错误信息
});
export default service
在src目录下新建一个api文件夹,然后建一个book.js文件来封装我们之前开发好的后端接口
import requset from '../utils/request'
// 获取书城列表分页条件查询
export function getBookInfoList(current,pageSize,param){
return requset({
url: `/book/list/${current}/${pageSize}`,
method: 'post',
data:param
})
}
// 新增书城书本信息
export function addBookInfo(param){
return requset({
url: `/book/add-one-book`,
method: 'post',
data:param
})
}
// 根据id获取书本信息
export function getBookInfoById(id){
return requset({
url: `/book/get-one-book/${id}`,
method: 'get'
})
}
// 根据id修改书本信息
export function updBookInfo(param){
return requset({
url: `/book/upd-one-book`,
method: 'post',
data:param
})
}
// 删除一本书
export function deleteOneBook(param){
return requset({
url: `/book/delete-one-book`,
method: 'post',
data:param
})
}
我是直接在HomeView.vue里写我的列表页面,然后我又在其平级页面建了book-add.vue和book-upd.vue来做新增页面和修改页面。
HomeView.vue
<template>
<div>
<div class="mod-user">
<el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
<el-form-item>
<el-input v-model="dataForm.name" placeholder="书名" clearable></el-input>
</el-form-item>
<el-form-item>
<el-button @click="getDataList()" type="warning">查询</el-button>
<el-button @click="addOneBookInfo()" type="success" plain>新增</el-button>
</el-form-item>
</el-form>
<el-table :data="dataList" border v-loading="dataListLoading" style="width: 100%;">
<el-table-column prop="id" header-align="center" align="center" width="120" label="序号">
</el-table-column>
<el-table-column header-align="center" align="center" width="120" label="图片">
<template v-slot="scope">
<img v-if="scope.row.picture !== undefined" :src="scope.row.picture" lazy style="width: 100px; height: 80px"/>
</template>
</el-table-column>
<el-table-column prop="name" header-align="center" align="center" width="180" label="书名">
</el-table-column>
<el-table-column prop="auth" header-align="center" align="center" width="180" label="作者">
</el-table-column>
<el-table-column prop="introduce" header-align="center" align="center" width="340" label="介绍">
</el-table-column>
<el-table-column prop="price" header-align="center" align="center" width="180" label="价格">
</el-table-column>
<el-table-column prop="publish" header-align="center" align="center" width="180" label="出版社">
</el-table-column>
<el-table-column prop="gmtCreate" header-align="center" align="center" width="180" label="出版时间">
</el-table-column>
<el-table-column fixed="right" header-align="center" align="center" width="150" label="操作">
<template v-slot="scope">
<el-button type="success" plain size="small" @click="updBookInfo(scope.row)">修改</el-button>
<el-button type="danger" plain size="small" @click="deleteHandle(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-pagination
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
:current-page="current"
:page-sizes="[10, 20, 50, 100]"
:page-size="pageSize"
:total="totalPage"
layout="total, sizes, prev, pager, next, jumper">
</el-pagination>
</div>
</div>
</template>
<script>
//这里可以导入其他文件(比如:组件,工具 js,第三方插件 js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';
import { getBookInfoList,deleteOneBook } from '@/api/book';
export default {
//import 引入的组件需要注入到对象中才能使用
components: {},
props: {},
data() {
//这里存放数据
return {
param:{},
dataForm:{
name:''
},
dataList: [],
pastDataList:[], //过滤数组
current: 1,
pageSize: 10,
totalPage: 0,
dataListLoading: false,
dataListSelections: [],
};
},
//计算属性 类似于 data 概念
computed: {},
//监控 data 中的数据变化
watch: {},
//方法集合
methods: {
getDataList(){
console.log("进入getDataList方法了");
this.param = {
"name":this.dataForm.name
}
this.dataListLoading = true;
getBookInfoList(this.current,this.pageSize,this.param).then((resp)=>{
console.log("调用getBookInfoList接口返回的数据是:",resp.data);
const {code,message,data} = resp.data;
if(code === '00000' && data && data.length != ""){
this.dataList = data.records;
this.totalPage = data.total;
}else{
this.dataList = [];
}
this.dataListLoading = false
})
},
// 每页数
sizeChangeHandle (val) {
this.pageSize = val
this.current = 1
this.getDataList()
},
// 当前页
currentChangeHandle (val) {
this.current = val
this.getDataList()
},
//新增书本商城信息
addOneBookInfo(){
this.$router.push({path:'book-add'});
},
//修改书城书本信息
updBookInfo(row){
console.log("要修改的书本信息是:",row);
//this.$router.push({path:'/anotherPage',query:{id:1}});
this.$router.push({path:'book-upd/'+row.id})
},
//删除
deleteHandle(row){
console.log("进入deleteHandle方法,要删除的那行数据是:",row);
this.param = {
'id':row.id
}
this.$confirm(`确定对这条数据进行删除删除操作吗,该操作执行成功后数据不可恢复?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(()=>{
deleteOneBook(this.param).then((resp)=>{
console.log("调用deleteOneBook接口返回的数据是:",resp.data);
const{code} = resp.data
if(code ==='00000'){
this.$message({
message:'操作成功',
type:'success',
duration:1500,
onClose:()=>{
this.getDataList()
}
})
}else{
this.$message({
message:'操作失败',
type:'error',
duration:1500,
onClose:()=>{
this.getDataList()
}
})
}
}).catch((error)=>{})
})
},
},
//生命周期 - 创建完成(可以访问当前 this 实例)
created() {
this.getDataList();
},
//生命周期 - 挂载完成(可以访问 DOM 元素)
mounted() {
},
beforeCreate() {}, //生命周期 - 创建之前
beforeMount() {}, //生命周期 - 挂载之前
beforeUpdate() {}, //生命周期 - 更新之前
updated() {}, //生命周期 - 更新之后
beforeDestroy() {}, //生命周期 - 销毁之前
destroyed() {}, //生命周期 - 销毁完成
activated() {}, //如果页面有 keep-alive 缓存功能,这个函数会触发
}
</script>
<style lang='scss' scoped>
//@import url(); 引入公共 css 类
</style>
book-add.vue
<template>
<h3 class="dialog-head">新增书本信息</h3>
<div class="mod-body">
<el-form :model="dataForm" :rules="dataRule" ref="dataForm" label-width="120px">
<el-form-item label="书本图片" prop="picture">
<el-upload
class="upload-demo"
action="http://localhost:8569/book/upload"
:on-preview="handlePreview"
:on-success="handleAvatarSuccess"
:on-remove="handleRemove"
:file-list="fileList"
list-type="picture">
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
</el-form-item>
<el-form-item label="书名" prop="name">
<el-input v-model="dataForm.name" type="input" placeholder="请填写书名" style="width:350px"></el-input>
</el-form-item>
<el-form-item label="作者" prop="auth">
<el-input v-model="dataForm.auth" type="input" placeholder="请填写作者姓名" style="width:350px"></el-input>
</el-form-item>
<el-form-item label="介绍" prop="introduce">
<el-input v-model="dataForm.introduce" type="textarea" :rows="2" placeholder="请填写介绍"></el-input>
</el-form-item>
<el-form-item label="定价" prop="price">
<el-input v-model="dataForm.price" type="input" placeholder="请填写定价" style="width:350px"></el-input>
</el-form-item>
<el-form-item label="出版社" prop="publish">
<el-input v-model="dataForm.publish" type="input" placeholder="请填写出版社" ></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="dataFormSubmit()">确定添加</el-button>
</span>
</div>
</template>
<script>
//这里可以导入其他文件(比如:组件,工具 js,第三方插件 js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';
import {addBookInfo} from '@/api/book'
export default {
//import 引入的组件需要注入到对象中才能使用
components: {},
props: {},
data() {
var validateContent = (rule, value, callback) => {
if (!this.dataForm.content && !/\S/.test(value)) {
callback(new Error('内容不能为空'))
} else {
callback()
}
}
//这里存放数据
return {
fileList:[],
param:{},
dataList:[],
dataForm:{
price:'',
name:'',
picture:'',
auth:'',
publish:'',
introduce:'',
},
pickerOptions: {},
dataRule:{
name:[
{required:true,message:'不能为空',trigger:'blur'}
],
auth:[
{required:true,message:'不能为空',trigger:'blur'}
],
introduce:[
{required:true,message:'不能为空',trigger:'blur'}
],
publish:[
{required:true,message:'不能为空',trigger:'blur'}
],
price:[
{required:true,message:'不能为空',trigger:'blur'}
]
}
};
},
//计算属性 类似于 data 概念
computed: {},
//监控 data 中的数据变化
watch: {},
//方法集合
methods: {
//表单提交
dataFormSubmit(){
this.$refs['dataForm'].validate((valid) => {
if(valid){
console.log("进入dataFormSubmit方法了");
this.param = {
'picture':this.dataForm.picture,
'name':this.dataForm.name,
'introduce':this.dataForm.introduce,
'publish':this.dataForm.publish,
'auth':this.dataForm.auth,
'price':this.dataForm.price,
}
addBookInfo(this.param).then((resp)=>{
console.log("调用addBookInfo接口返回的数据是:",resp.data);
const {code,message} = resp.data
if(code ==='00000'){
this.$message({
message:'操作成功',
type:'success',
duration:1500,
onClose:()=>{
this.dataForm={};
this.$router.push({path:'/'})
}
})
}
}).catch((error)=>{
console.log(error);
});
}
})
},
//上传图片
handleRemove(file, fileList) {
// console.log(file, fileList);
// console.log("图片上传成功返回的访问路径是:",file.response.data);
// console.log("此时dataForm里面picture路径是:",this.dataForm.picture);
},
handlePreview(file) {
// console.log("图片上传成功返回的访问路径是:",file.response.data);
// console.log(file);
},
handleAvatarSuccess(res, file) {
console.log("图片上传成功返回的访问路径是:",file.response.data);
this.dataForm.picture = file.response.data
// console.log("此时dataForm里面picture路径是:",this.dataForm.picture);
},
},
//生命周期 - 创建完成(可以访问当前 this 实例)
created() {
},
//生命周期 - 挂载完成(可以访问 DOM 元素)
mounted() {},
beforeCreate() {}, //生命周期 - 创建之前
beforeMount() {}, //生命周期 - 挂载之前
beforeUpdate() {}, //生命周期 - 更新之前
updated() {}, //生命周期 - 更新之后
beforeDestroy() {}, //生命周期 - 销毁之前
destroyed() {}, //生命周期 - 销毁完成
activated() {} //如果页面有 keep-alive 缓存功能,这个函数会触发
};
</script>
<style lang="scss" scoped>
.dialog-footer{
margin-left: 70%;
}
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
</style>
book-upd.vue
<template>
<h3 class="dialog-head">修改书本信息</h3>
<div class="mod-body">
<el-form :model="dataForm" :rules="dataRule" ref="dataForm" label-width="120px">
<el-form-item label="书本序号" prop="id">
<el-input v-model="dataForm.id" type="input" disabled style="width:350px"></el-input>
</el-form-item>
<el-form-item label="书本图片" prop="picture">
<el-upload
class="upload-demo"
action="http://localhost:8569/book/upload"
:on-preview="handlePreview"
:on-success="handleAvatarSuccess"
:on-remove="handleRemove"
:file-list="fileList"
list-type="picture">
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
</el-form-item>
<el-form-item label="书名" prop="name">
<el-input v-model="dataForm.name" type="text" style="width:350px"></el-input>
</el-form-item>
<el-form-item label="作者" prop="auth">
<el-input v-model="dataForm.auth" type="input" style="width:350px"></el-input>
</el-form-item>
<el-form-item label="介绍" prop="introduce">
<el-input v-model="dataForm.introduce" type="textarea" :rows="2" ></el-input>
</el-form-item>
<el-form-item label="定价" prop="price">
<el-input v-model="dataForm.price" type="input" style="width:350px"></el-input>
</el-form-item>
<el-form-item label="出版社" prop="publish">
<el-input v-model="dataForm.publish" type="input"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="dataFormSubmit()">确定修改</el-button>
</span>
</div>
</template>
<script>
//这里可以导入其他文件(比如:组件,工具 js,第三方插件 js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';
import {updBookInfo,getBookInfoById} from '@/api/book'
export default {
//import 引入的组件需要注入到对象中才能使用
components: {},
props: {},
data() {
var validateContent = (rule, value, callback) => {
if (!this.dataForm.content && !/\S/.test(value)) {
callback(new Error('内容不能为空'))
} else {
callback()
}
}
//这里存放数据
return {
fileList:[],
param:{},
dataList:[],
dataForm:{
id:'',
price:'',
name:'',
auth:'',
publish:'',
introduce:'',
},
pickerOptions: {},
dataRule:{
name:[
{required:true,message:'不能为空',trigger:'blur'}
],
auth:[
{required:true,message:'不能为空',trigger:'blur'}
],
introduce:[
{required:true,message:'不能为空',trigger:'blur'}
],
publish:[
{required:true,message:'不能为空',trigger:'blur'}
],
price:[
{required:true,message:'不能为空',trigger:'blur'}
]
}
};
},
//计算属性 类似于 data 概念
computed: {},
//监控 data 中的数据变化
watch: {},
//方法集合
methods: {
//回填数据
backDataDetail(){
const id = this.$route.params.id
console.log("从页面路径上获取下来的书本id是:",id);
getBookInfoById(id).then((resp)=>{
console.log("调用getBookInfoById接口返回的信息是:",resp.data);
const {code,data} = resp.data
if(code === '00000'){
this.dataForm.id = data.id
this.fileList = [{url:data.picture}]
this.dataForm.name = data.name
this.dataForm.auth = data.auth
this.dataForm.introduce = data.introduce
this.dataForm.price = data.price
this.dataForm.publish = data.publish
}
})
},
//上传图片
handleRemove(file, fileList) {
console.log(file,fileList);
},
handlePreview(file) {
console.log(file);
},
handleAvatarSuccess(res, file) {
console.log("图片上传成功返回的访问路径是:",file.response.data);
this.dataForm.picture = file.response.data
// console.log("此时dataForm里面picture路径是:",this.dataForm.picture);
},
//修改书本
//表单提交
dataFormSubmit(){
this.$refs['dataForm'].validate((valid) => {
if(valid){
console.log("进入dataFormSubmit方法了");
this.param = {
'id':this.dataForm.id,
'picture':this.dataForm.picture,
'name':this.dataForm.name,
'introduce':this.dataForm.introduce,
'publish':this.dataForm.publish,
'auth':this.dataForm.auth,
'price':this.dataForm.price,
}
updBookInfo(this.param).then((resp)=>{
console.log("调用updBookInfo接口返回的数据是:",resp.data);
const {code,message} = resp.data
if(code ==='00000'){
this.$message({
message:'操作成功',
type:'success',
duration:1500,
onClose:()=>{
this.dataForm={};
this.$router.push({path:'/'})
}
})
}
}).catch((error)=>{
console.log(error);
});
}
})
},
},
//生命周期 - 创建完成(可以访问当前 this 实例)
created() {
this.backDataDetail();
},
//生命周期 - 挂载完成(可以访问 DOM 元素)
mounted() {},
beforeCreate() {}, //生命周期 - 创建之前
beforeMount() {}, //生命周期 - 挂载之前
beforeUpdate() {}, //生命周期 - 更新之前
updated() {}, //生命周期 - 更新之后
beforeDestroy() {}, //生命周期 - 销毁之前
destroyed() {}, //生命周期 - 销毁完成
activated() {} //如果页面有 keep-alive 缓存功能,这个函数会触发
};
</script>
<style lang="scss" scoped>
.dialog-footer{
margin-left: 70%;
}
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
</style>
然后在src目录下router文件夹下的index.js里面配置一下新增和修改的跳转路由
{
path: '/book-add',
name: 'addBook',
component: ()=> import('../views/book-add.vue')
},
{
path: '/book-upd/:id',
name: 'updBook',
component: ()=> import('../views/book-upd.vue')
}
至此,这个超级无敌简单的项目就开发好了!多联系联系就行。文章来源地址https://www.toymoban.com/news/detail-478274.html
到了这里,关于书城管理系统(前端)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!