书城管理系统(前端)

OK,兄弟们!

测试上传图片的后端接口

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

 测试根据id查询后端接口

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

 

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

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

准备工作:

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

(3条消息) Vue脚手架搭建及vue项目创建【详细教程】_星河梦~的博客-CSDN博客icon-default.png?t=N2N8https://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')
  }

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

猜你喜欢

转载自blog.csdn.net/weixin_46511995/article/details/130214926