书城管理系统(前端)

我的火龙果呢 2024-06-19 16:03:09 阅读 78

OK,兄弟们!

测试上传图片的后端接口

 测试分页条件查询后端接口

 测试根据id查询后端接口

测试新增一本书的后端接口

 

 测试修改一本书的后端接口

 

之前写好的后端接口,用postman测试一下,没有问题的话我们就试试开发前端。

准备工作:

用vue创建一个文件,安装VUE步骤我这里引用一下其他人的csdn

(3条消息) Vue脚手架搭建及vue项目创建【详细教程】_星河梦~的博客-CSDN博客

icon-default.png?t=N2N8

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') }

至此,这个超级无敌简单的项目就开发好了!多联系联系就行。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。