【Spring Boot + Vue 前后端分离 - 图书管理Demo】——【二】查操作


👉 【Spring Boot + Vue 前后端分离 - 图书管理Demo】——【一】环境准备

👉 GitHub源码地址


一、 主界面样式

在这里插入图片描述
根据Element官网给出的样式实例代码进行相关修改

👉 Element用户手册
在这里插入图片描述
修改后的App.Vue 如下

<template>
  <div id="app">
    <el-container style="height: 500px; border: 1px solid #eee">
      <el-aside width="200px" style="background-color: rgb(238, 241, 246)">
        <el-menu :default-openeds="['1', '3']">
          <el-submenu index="1">
            <template slot="title"><i class="el-icon-message"></i>导航一</template>
            <el-menu-item-group>
              <template slot="title">分组一</template>
              <el-menu-item index="1-1">选项1</el-menu-item>
              <el-menu-item index="1-2">选项2</el-menu-item>
            </el-menu-item-group>
          </el-submenu>            
        </el-menu>
      </el-aside>
      
      <el-main>
        <router-view></router-view>
      </el-main>
      
    </el-container>
  </div>
</template>

<style>
  .el-header {
    background-color: #B3C0D1;
    color: #333;
    line-height: 60px;
  }

  .el-aside {
    color: #333;
  }
</style>

<script>
  export default {
    data() {
      const item = {
        date: '2016-05-02',
        name: '王小虎',
        address: '上海市普陀区金沙江路 1518 弄'
      };
      return {
        tableData: Array(20).fill(item)
      }
    }
  };
</script>

在这里插入图片描述

新建index.vue
在这里插入图片描述

<template>
    <router-view></router-view>
</template>

<script>
    export default {
        name: "Index"
    }
</script>

<style scoped>

</style>
  • App.Vue 实现整体框架(侧边栏),每次页面跳转的时候这个框架的样式是不变的.
  • App.vue 中的router-viewindexindexrouter-view 套其他界面,这样才能保证侧边栏一直存在。此后的每次页面跳转都只更改index的router-view中的内容

在这里插入图片描述


二、 menu 与 router的绑定,实现页面跳转

1. 新建前端页面

在views中新建

  • BookManager.vue (查询图书页面)、
  • BookUpdate.vue(图书信息修改页面)、
  • AddBook.vue(添加图书页面)`
2. 配置路由(router/index.js )
import Vue from 'vue'
import VueRouter from 'vue-router'
import Index from "../views/Index";
import BookManager from "../views/BookManager";
import AddBook from "../views/AddBook";
import BookUpdate from "../views/BookUpdate";


Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: '图书管理',
    show: true,
    component: Index,
    /* 首页地址直接跳转到/BookManager */
    redirect: "/BookManager",
    children: [
      {
        path: '/BookManager',
        name: '查询图书',
        component: BookManager
      },
      {
        path: '/AddBook',
        name: '添加图书',
        component: AddBook
      },

    ]
  },

  {
    path: '/BookUpdate',
    // name: '修改图书',
    component: BookUpdate,
    show: false
  }

]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router

3. 修改App.vue, 实现menu 与 router的绑定(页面跳转)
  • 标签添加router属性
  • 在index页面中添加route-view标签,他是一个容器,动态渲染你选择的router
  • el-menu-item标签的index值就是要跳转的router
<template>
  <div id="app">
    <el-container style="height: 700px; border: 1px solid #eee">

      <el-aside width="200px" style="background-color: rgb(238, 241, 246)">

        <el-menu router :default-openeds="['0', '1']">
          <!--循环遍历routes中的对象,有几个对象就有几个item-->
          <!--添加index属性标识不同的submenu-->
          <!--默认的index是字符串类型,而不是整数类型,多以需要转化为字符类型-->
          <!--v-if=item.show 表示根据路由配置中的show:ture/false决定是否显示该菜单 -->
          <el-submenu v-for="(item,index) in $router.options.routes" :index="index+''" v-if="item.show">
            <template slot="title"><i class="el-icon-setting"></i>{{item.name}}</template>
            <el-menu-item v-for="(item2,index2) in item.children" :index="item2.path"
                          :class="$route.path==item2.path?'is-active':''">{{item2.name}}</el-menu-item>
          </el-submenu>
        </el-menu>

      </el-aside>

      <el-main>
        <router-view></router-view>
      </el-main>

    </el-container>
  </div>
</template>

三、前后端信息传递,显示图书信息

1. JPA 连接数据库配置

application.yml

spring:
  datasource:
  	# 连接数据库library
    url: jdbc:mysql://localhost:3306/library?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    # 打印sql
    show-sql: true
    properties:
      hibernate:
        # 格式化sql
        format_sql: true
        
server:
  port: 8181

vue已经默认占用了8080端口,修改springboot的端口为8181防止冲突

2. 整合SpringData JPA, 编写一个实体类(bean)和数据表进行映射

在spring boot项目中新建实体类 entity/Book.java

/**
 * 使用Entity将该类与数据库表绑定,根据类名和表名经行绑定(默认类名小写就是表名);
 *
 * Data是lombok插件的方法,自动帮我们生成各种setter和getter方法
 */
@Entity
@Data
public class Book {
    // 和数据库表中的id绑定,表示这是主键
    @Id
    // 设置主键Id自增
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private String author;
    private String publish;
    private Integer pages;
    private Integer price;
}
3. 编写一个Dao接口来操作实体类对应的数据表(Repository)

新建 repository/ BookRepository.java

Spring Data 提供了统一的 repository 接口,实现了数据库的相关基本操作
在这里插入图片描述
继承 JpaRepository 来完成对数据库的操作

public interface BookRepository extends JpaRepository<Book, Integer> {

}
4. 新建Controller层处理浏览器请求

controller/ BookHandler.java

/**
 * RestController = @Controller + @ResponseBody
 * Controller 将当前修饰的类注入SpringBoot IOC容器,使得从该类所在的项目跑起来的过程中,这个类就被实例化。
 * 当然也有语义化的作用,即代表该类是充当Controller的作用
 * ResponseBody 该类中所有的API接口返回的数据都会以Json字符串的形式返回给客户端
 *
 * RequestMapping 提供路由信息,负责URL到Controller中的具体函数的映射。服务器发送 /book 请求时执行该类
 *
 * 通过Handler数据才能调给前端使用
 */
@RestController
@RequestMapping("/book")
public class BookHandler {
    @Autowired
    private BookRepository bookRepository;

    /**
     * 分页显示
     *
     * GetMapping是一个组合注解 是@RequestMapping(method = RequestMethod.GET)的缩写
     * page/size 表示从第几页开始,每页几个
     */
    @GetMapping("/findAll/{page}/{size}")
    public Page<Book> findAll(@PathVariable("page") Integer page, @PathVariable("size") Integer size){
        PageRequest request = PageRequest.of(page,size);
        return bookRepository.findAll(request);
    }
}

运行该项目

http://localhost:8181/book/findAll/0/6 表示从第0页开始,显示6个数据

5. 前端发送Ajax请求8181端口获取后端数据

通过 axios 组件请求 Ajax
axios 是目前应用最为广泛的 Ajax 封装库

  1. 终止vue服务后 在命令行输入vue add axios 安装axios
    在这里插入图片描述
  2. 修改 BookManager.vue
  • created() 方法页面一打开就会调用
  • page() 方法实现点击页数跳转
   		<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>
                    <!--delete是关键字,不能自定义-->
                </template>
         </el-table-column> 

        <el-pagination
                background
                layout="prev, pager, next"
                :page-size="pageSize"
                :total="total"
                @current-change="page">
                <!--点击页数跳转-->
        </el-pagination>
    
    
<script>
    export default {
        methods: {

            page(currentPage){
                const _this = this
                <!--通过axios发送ajax 请求后端数据-->
                axios.get('http://localhost:8181/book/findAll/'+(currentPage-1)+'/10').then(function(resp){
                    console.log(resp)
                    _this.tableData = resp.data.content
                    _this.pageSize = resp.data.size
                    _this.total = resp.data.totalElements
                })
            }
        },

        data() {
            return {
                pageSize: '',
                total: '',
                tableData: [
                ]
            }
        },

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

访问 http://localhost:8080/BookManager (刷新浏览器)
查看控制台,出现跨域问题,前端无法获取后端数据
在这里插入图片描述

6. 解决跨域问题

在后端解决跨域问题:
新建配置类 config/ CrosConfig.java

/**
 * 解决跨域问题
 */
@Configuration
public class CrosConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
                .allowCredentials(true)
                .maxAge(3600)
                .allowedHeaders("*");
    }
}
  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞天小牛肉

您的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值