前后端分离项目学习笔记

该项目为一个基于Springboot+vue实现前后端分离的图书管理项目。

1.首先新建一个springboottest工程,负责完成后端的业务逻辑操作,不需要写页面。

1)先定义实体类Book,然后定义一个数据库层的接口BookRepository,该接口继承了JpaRepository,spring data jpa 默认预先生成了一些基本的CURD的方法,例如:增、删、改等等。最后定义控制层BookHandler,负责和前端页面交互(接收前端增删改查请求)。配置类中CroConfig负责解决跨域问题。代码写好后在idea中启动该项目,随后开始写前端代码。

 其中BookHandler代码如下:

 1 package com.southwind.springboottest.controller;
 2 
 3 import com.southwind.springboottest.entity.Book;
 4 import com.southwind.springboottest.repository.BookRepository;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.data.domain.Page;
 7 import org.springframework.data.domain.PageRequest;
 8 import org.springframework.web.bind.annotation.*;
 9 
10 @RestController
11 @RequestMapping("/book")
12 public class BookHandler {
13     @Autowired
14     private BookRepository bookRepository;
15 
16     @GetMapping("/findAll/{page}/{size}")
17     public Page<Book> findAll(@PathVariable("page") Integer page, @PathVariable("size") Integer size){
18         PageRequest request = PageRequest.of(page,size);
19         return bookRepository.findAll(request);
20     }
21 
22     @PostMapping("/save")
23     public String save(@RequestBody Book book){
24         Book result = bookRepository.save(book);
25         if(result != null){
26             return "success";
27         }else{
28             return "error";
29         }
30     }
31 
32     @GetMapping("/findById/{id}")
33     public Book findById(@PathVariable("id") Integer id){
34         return bookRepository.findById(id).get();
35     }
36 
37     @PutMapping("/update")
38     public String update(@RequestBody Book book){
39         Book result = bookRepository.save(book);
40         if(result != null){
41             return "success";
42         }else{
43             return "error";
44         }
45     }
46 
47     @DeleteMapping("/deleteById/{id}")
48     public void deleteById(@PathVariable("id") Integer id){
49         bookRepository.deleteById(id);
50     }
51 }

2.前端部分

首先安装nodejs和vue。

cmd窗口输入vue ui 命令以图形化界面创建和管理项目,输入http://localhost:8000/project/select创建一个Vue项目。创建完后在idea中打开该项目进行开发。

 在idea中打开该vue项目,通过router目录下index.js编写页面路由routes。如下图所示:

 router/index.js如下:

 1 import Vue from 'vue'
 2 import VueRouter from 'vue-router'
 3 import BookManage from '../views/BookManage'
 4 import AddBook from '../views/AddBook'
 5 import Index from '../views/Index'
 6 import BookUpdate from '../views/BookUpdate'
 7 
 8 Vue.use(VueRouter)
 9 
10 const routes = [
11   {
12     path:"/",
13     name:"图书管理",
14     component:Index,
15     show:true,
16     redirect:"/BookManage",
17     children:[
18       {
19         path:"/BookManage",
20         name:"查询图书",
21         component:BookManage
22       },
23       {
24         path:"/AddBook",
25         name:"添加图书",
26         component:AddBook
27       }
28     ]
29   },
30   {
31     path:'/update',
32     component:BookUpdate,
33     show:false
34   }
35 ]
36 
37 const router = new VueRouter({
38   mode: 'history',
39   base: process.env.BASE_URL,
40   routes
41 })
42 
43 export default router

配置好路由后,编写前端页面:

BookManage.vue

<template>
    <div>
        <el-table
                :data="tableData"
                border
                style=" 70%">
            <el-table-column
                    fixed
                    prop="id"
                    label="编号"
                    width="150">
            </el-table-column>
            <el-table-column
                    prop="name"
                    label="图书名"
                    width="120">
            </el-table-column>
            <el-table-column
                    prop="author"
                    label="作者"
                    width="120">
            </el-table-column>
            <el-table-column
                    fixed="right"
                    label="操作"
                    width="100">
                <template slot-scope="scope">
                    <el-button @click="edit(scope.row)" type="text" size="small">修改</el-button>
                    <el-button @click="deleteBook(scope.row)" type="text" size="small">删除</el-button>
                </template>
            </el-table-column>
        </el-table>

        <el-pagination
                background
                layout="prev, pager, next"
                :page-size="pageSize"
                :total="total"
                @current-change="page">
        </el-pagination>
    </div>
</template>

<script>
    export default {
        methods: {
            deleteBook(row){
                const _this = this
                axios.delete('http://localhost:8181/book/deleteById/'+row.id).then(function(resp){
                    _this.$alert('《'+row.name+'》删除成功!', '消息', {
                        confirmButtonText: '确定',
                        callback: action => {
                            window.location.reload()
                        }
                    })
                })
            },
            edit(row) {
                this.$router.push({
                    path: '/update',
                    query:{
                        id:row.id
                    }
                })
            },
            page(currentPage){
                const _this = this
                axios.get('http://localhost:8181/book/findAll/'+(currentPage-1)+'/6').then(function(resp){
                    console.log(resp)
                    _this.tableData = resp.data.content
                    _this.pageSize = resp.data.size
                    _this.total = resp.data.totalElements
                })
            }
        },

        data() {
            return {
                pageSize:'1',
                total:'11',
                tableData: [{
                    id: 1,
                    name: '解忧杂货店',
                    author: '东野圭吾'
                }, {
                    id: 2,
                    name: '追风筝的人',
                    author: '卡勒德·胡赛尼'
                }, {
                    id: 3,
                    name: '人间失格',
                    author: '太宰治'
                }]
            }
        },

        created() {
            const _this = this
            axios.get('http://localhost:8181/book/findAll/0/6').then(function(resp){
                console.log(resp)
                _this.tableData = resp.data.content
                _this.pageSize = resp.data.size
                _this.total = resp.data.totalElements
            })
        }
    }
</script>

AddBook.vue:

 1 <template>
 2     <el-form style=" 60%" :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
 3 
 4         <el-form-item label="图书名称" prop="name">
 5             <el-input v-model="ruleForm.name"></el-input>
 6         </el-form-item>
 7 
 8         <el-form-item label="作者" prop="author">
 9             <el-input v-model="ruleForm.author"></el-input>
10         </el-form-item>
11 
12         <el-form-item>
13             <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
14             <el-button @click="resetForm('ruleForm')">重置</el-button>
15         </el-form-item>
16 
17     </el-form>
18 </template>
19 
20 <script>
21     export default {
22         data() {
23             return {
24                 ruleForm: {
25                     name: '',
26                     author: ''
27                 },
28                 rules: {
29                     name: [
30                         { required: true, message: '图书名称不能为空', trigger: 'blur' }
31                     ],
32                     author:[
33                         { required: true, message: '作者不能为空', trigger: 'blur' }
34                     ]
35                 }
36             };
37         },
38         methods: {
39             submitForm(formName) {
40                 const _this = this
41                 this.$refs[formName].validate((valid) => {
42                     if (valid) {
43                         axios.post('http://localhost:8181/book/save',this.ruleForm).then(function(resp){
44                             if(resp.data == 'success'){
45                                 _this.$alert('《'+_this.ruleForm.name+'》添加成功!', '消息', {
46                                     confirmButtonText: '确定',
47                                     callback: action => {
48                                         _this.$router.push('/BookManage')
49                                     }
50                                 })
51                             }
52                         })
53                     } else {
54                         return false;
55                     }
56                 });
57             },
58             resetForm(formName) {
59                 this.$refs[formName].resetFields();
60             }
61         }
62     }
63 </script>

BookUpdate.vue

 1 <template>
 2     <el-form style=" 60%" :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
 3 
 4         <el-form-item label="图书编号">
 5             <el-input v-model="ruleForm.id" readOnly></el-input>
 6         </el-form-item>
 7 
 8         <el-form-item label="图书名称" prop="name">
 9             <el-input v-model="ruleForm.name"></el-input>
10         </el-form-item>
11 
12         <el-form-item label="作者" prop="author">
13             <el-input v-model="ruleForm.author"></el-input>
14         </el-form-item>
15 
16         <el-form-item>
17             <el-button type="primary" @click="submitForm('ruleForm')">修改</el-button>
18             <el-button @click="resetForm('ruleForm')">重置</el-button>
19         </el-form-item>
20 
21     </el-form>
22 </template>
23 
24 <script>
25     export default {
26         data() {
27             return {
28                 ruleForm: {
29                     id: '',
30                     name: '',
31                     author: ''
32                 },
33                 rules: {
34                     name: [
35                         { required: true, message: '图书名称不能为空', trigger: 'blur' }
36                     ],
37                     author:[
38                         { required: true, message: '作者不能为空', trigger: 'blur' }
39                     ]
40                 }
41             };
42         },
43         methods: {
44             submitForm(formName) {
45                 const _this = this
46                 this.$refs[formName].validate((valid) => {
47                     if (valid) {
48                         axios.put('http://localhost:8181/book/update',this.ruleForm).then(function(resp){
49                             if(resp.data == 'success'){
50                                 _this.$alert('《'+_this.ruleForm.name+'》修改成功!', '消息', {
51                                     confirmButtonText: '确定',
52                                     callback: action => {
53                                         _this.$router.push('/BookManage')
54                                     }
55                                 })
56                             }
57                         })
58                     } else {
59                         return false;
60                     }
61                 });
62             },
63             resetForm(formName) {
64                 this.$refs[formName].resetFields();
65             }
66         },
67         created() {
68             const _this = this
69             axios.get('http://localhost:8181/book/findById/'+this.$route.query.id).then(function(resp){
70                 _this.ruleForm = resp.data
71             })
72         }
73     }
74 </script>

至此前端页面写完,然后在终端Terminal输入npm run serve 运行该vue项目,点击http://localhost:8080/页面如下所示:(注意后端中为避免端口号冲突改成了8181,前端是8080)

mysql数据库:

原文地址:https://www.cnblogs.com/jingpeng77/p/14454312.html