【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("*");
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章