OK,兄弟們!
測(cè)試上傳圖片的后端接口
?測(cè)試分頁條件查詢后端接口
?測(cè)試根據(jù)id查詢后端接口
測(cè)試新增一本書的后端接口
?
?測(cè)試修改一本書的后端接口
?文章來源:http://www.zghlxwxcb.cn/news/detail-478274.html
之前寫好的后端接口,用postman測(cè)試一下,沒有問題的話我們就試試開發(fā)前端。
準(zhǔn)備工作:
用vue創(chuàng)建一個(gè)文件,安裝VUE步驟我這里引用一下其他人的csdn
(3條消息) Vue腳手架搭建及vue項(xiàng)目創(chuàng)建【詳細(xì)教程】_星河夢(mèng)~的博客-CSDN博客https://blog.csdn.net/weixin_53186633/article/details/122461313現(xiàn)在桌面創(chuàng)建一個(gè)空的文件夾,然后選擇用vscode打開,然后打開終端。
?然后在終端輸入vue命令新建一個(gè)vue項(xiàng)目
vue create book-fornt
然后選擇Manually select features,這里我們選下面這5個(gè)。按空格和上下箭頭選擇,選好回車就行
?然后這里我們選3.x
?下面按這個(gè)選擇配置就行,選好最后回車就開始創(chuàng)建了
?創(chuàng)建好就是這個(gè)樣子
?我們?cè)诮K端上切到book-fornt項(xiàng)目
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文件里的內(nèi)容
const { defineConfig } = require('@vue/cli-service')
module.exports = {
devServer:{
port:8020, // 啟動(dòng)端口號(hào)
open:true // 啟動(dòng)后是否自動(dòng)打開網(wǎng)頁
}
}
npm run serve跑一下試試,看看項(xiàng)目能不能運(yùn)行。
都沒問題的話我們才能開始開發(fā)前端內(nèi)容。
開發(fā)步驟:
先封裝前端請(qǐng)求request.js文件
在src目錄下新建一個(gè)utils文件夾,然后創(chuàng)建一個(gè)request.js來封裝axios請(qǐng)求?
request.js,再上一篇內(nèi)容里我們的后端接口是
import axios from 'axios'
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 創(chuàng)建axios實(shí)例
const service = axios.create({
// axios中請(qǐng)求配置有baseURL選項(xiàng),表示請(qǐng)求URL公共部分
baseURL: 'http://localhost:8785',
// 超時(shí)
timeout: 10000
})
//第三步 創(chuàng)建攔截器 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) // 返回接口返回的錯(cuò)誤信息
});
export default service
在src目錄下新建一個(gè)api文件夾,然后建一個(gè)book.js文件來封裝我們之前開發(fā)好的后端接口
?
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
})
}
// 根據(jù)id獲取書本信息
export function getBookInfoById(id){
return requset({
url: `/book/get-one-book/${id}`,
method: 'get'
})
}
// 根據(jù)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里寫我的列表頁面,然后我又在其平級(jí)頁面建了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="序號(hào)">
</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="價(jià)格">
</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="出版時(shí)間">
</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>
//這里可以導(dǎo)入其他文件(比如:組件,工具 js,第三方插件 js,json文件,圖片文件等等)
//例如:import 《組件名稱》 from '《組件路徑》';
import { getBookInfoList,deleteOneBook } from '@/api/book';
export default {
//import 引入的組件需要注入到對(duì)象中才能使用
components: {},
props: {},
data() {
//這里存放數(shù)據(jù)
return {
param:{},
dataForm:{
name:''
},
dataList: [],
pastDataList:[], //過濾數(shù)組
current: 1,
pageSize: 10,
totalPage: 0,
dataListLoading: false,
dataListSelections: [],
};
},
//計(jì)算屬性 類似于 data 概念
computed: {},
//監(jiān)控 data 中的數(shù)據(jù)變化
watch: {},
//方法集合
methods: {
getDataList(){
console.log("進(jìn)入getDataList方法了");
this.param = {
"name":this.dataForm.name
}
this.dataListLoading = true;
getBookInfoList(this.current,this.pageSize,this.param).then((resp)=>{
console.log("調(diào)用getBookInfoList接口返回的數(shù)據(jù)是:",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
})
},
// 每頁數(shù)
sizeChangeHandle (val) {
this.pageSize = val
this.current = 1
this.getDataList()
},
// 當(dāng)前頁
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("進(jìn)入deleteHandle方法,要?jiǎng)h除的那行數(shù)據(jù)是:",row);
this.param = {
'id':row.id
}
this.$confirm(`確定對(duì)這條數(shù)據(jù)進(jìn)行刪除刪除操作嗎,該操作執(zhí)行成功后數(shù)據(jù)不可恢復(fù)?`, '提示', {
confirmButtonText: '確定',
cancelButtonText: '取消',
type: 'warning'
}).then(()=>{
deleteOneBook(this.param).then((resp)=>{
console.log("調(diào)用deleteOneBook接口返回的數(shù)據(jù)是:",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)=>{})
})
},
},
//生命周期 - 創(chuàng)建完成(可以訪問當(dāng)前 this 實(shí)例)
created() {
this.getDataList();
},
//生命周期 - 掛載完成(可以訪問 DOM 元素)
mounted() {
},
beforeCreate() {}, //生命周期 - 創(chuàng)建之前
beforeMount() {}, //生命周期 - 掛載之前
beforeUpdate() {}, //生命周期 - 更新之前
updated() {}, //生命周期 - 更新之后
beforeDestroy() {}, //生命周期 - 銷毀之前
destroyed() {}, //生命周期 - 銷毀完成
activated() {}, //如果頁面有 keep-alive 緩存功能,這個(gè)函數(shù)會(huì)觸發(fā)
}
</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">點(diǎn)擊上傳</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="請(qǐng)?zhí)顚憰? style="width:350px"></el-input>
</el-form-item>
<el-form-item label="作者" prop="auth">
<el-input v-model="dataForm.auth" type="input" placeholder="請(qǐng)?zhí)顚懽髡咝彰? 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="請(qǐng)?zhí)顚懡榻B"></el-input>
</el-form-item>
<el-form-item label="定價(jià)" prop="price">
<el-input v-model="dataForm.price" type="input" placeholder="請(qǐng)?zhí)顚懚▋r(jià)" style="width:350px"></el-input>
</el-form-item>
<el-form-item label="出版社" prop="publish">
<el-input v-model="dataForm.publish" type="input" placeholder="請(qǐng)?zhí)顚懗霭嫔? ></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>
//這里可以導(dǎo)入其他文件(比如:組件,工具 js,第三方插件 js,json文件,圖片文件等等)
//例如:import 《組件名稱》 from '《組件路徑》';
import {addBookInfo} from '@/api/book'
export default {
//import 引入的組件需要注入到對(duì)象中才能使用
components: {},
props: {},
data() {
var validateContent = (rule, value, callback) => {
if (!this.dataForm.content && !/\S/.test(value)) {
callback(new Error('內(nèi)容不能為空'))
} else {
callback()
}
}
//這里存放數(shù)據(jù)
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'}
]
}
};
},
//計(jì)算屬性 類似于 data 概念
computed: {},
//監(jiān)控 data 中的數(shù)據(jù)變化
watch: {},
//方法集合
methods: {
//表單提交
dataFormSubmit(){
this.$refs['dataForm'].validate((valid) => {
if(valid){
console.log("進(jìn)入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("調(diào)用addBookInfo接口返回的數(shù)據(jù)是:",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("此時(shí)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("此時(shí)dataForm里面picture路徑是:",this.dataForm.picture);
},
},
//生命周期 - 創(chuàng)建完成(可以訪問當(dāng)前 this 實(shí)例)
created() {
},
//生命周期 - 掛載完成(可以訪問 DOM 元素)
mounted() {},
beforeCreate() {}, //生命周期 - 創(chuàng)建之前
beforeMount() {}, //生命周期 - 掛載之前
beforeUpdate() {}, //生命周期 - 更新之前
updated() {}, //生命周期 - 更新之后
beforeDestroy() {}, //生命周期 - 銷毀之前
destroyed() {}, //生命周期 - 銷毀完成
activated() {} //如果頁面有 keep-alive 緩存功能,這個(gè)函數(shù)會(huì)觸發(fā)
};
</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="書本序號(hào)" 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">點(diǎn)擊上傳</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="定價(jià)" 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>
//這里可以導(dǎo)入其他文件(比如:組件,工具 js,第三方插件 js,json文件,圖片文件等等)
//例如:import 《組件名稱》 from '《組件路徑》';
import {updBookInfo,getBookInfoById} from '@/api/book'
export default {
//import 引入的組件需要注入到對(duì)象中才能使用
components: {},
props: {},
data() {
var validateContent = (rule, value, callback) => {
if (!this.dataForm.content && !/\S/.test(value)) {
callback(new Error('內(nèi)容不能為空'))
} else {
callback()
}
}
//這里存放數(shù)據(jù)
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'}
]
}
};
},
//計(jì)算屬性 類似于 data 概念
computed: {},
//監(jiān)控 data 中的數(shù)據(jù)變化
watch: {},
//方法集合
methods: {
//回填數(shù)據(jù)
backDataDetail(){
const id = this.$route.params.id
console.log("從頁面路徑上獲取下來的書本id是:",id);
getBookInfoById(id).then((resp)=>{
console.log("調(diào)用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("此時(shí)dataForm里面picture路徑是:",this.dataForm.picture);
},
//修改書本
//表單提交
dataFormSubmit(){
this.$refs['dataForm'].validate((valid) => {
if(valid){
console.log("進(jìn)入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("調(diào)用updBookInfo接口返回的數(shù)據(jù)是:",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);
});
}
})
},
},
//生命周期 - 創(chuàng)建完成(可以訪問當(dāng)前 this 實(shí)例)
created() {
this.backDataDetail();
},
//生命周期 - 掛載完成(可以訪問 DOM 元素)
mounted() {},
beforeCreate() {}, //生命周期 - 創(chuàng)建之前
beforeMount() {}, //生命周期 - 掛載之前
beforeUpdate() {}, //生命周期 - 更新之前
updated() {}, //生命周期 - 更新之后
beforeDestroy() {}, //生命周期 - 銷毀之前
destroyed() {}, //生命周期 - 銷毀完成
activated() {} //如果頁面有 keep-alive 緩存功能,這個(gè)函數(shù)會(huì)觸發(fā)
};
</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里面配置一下新增和修改的跳轉(zhuǎn)路由
?
{
path: '/book-add',
name: 'addBook',
component: ()=> import('../views/book-add.vue')
},
{
path: '/book-upd/:id',
name: 'updBook',
component: ()=> import('../views/book-upd.vue')
}
至此,這個(gè)超級(jí)無敵簡(jiǎn)單的項(xiàng)目就開發(fā)好了!多聯(lián)系聯(lián)系就行。文章來源地址http://www.zghlxwxcb.cn/news/detail-478274.html
到了這里,關(guān)于書城管理系統(tǒng)(前端)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!