SpringBoot系列教材 (三十五)- Thymeleaf - Vue.js + Restful + PageHelper + Thymeleaf + Springboot 前后端分离 增删改查

步骤1:教程说明
步骤2:数据库准备
步骤3:准备表
步骤4:先运行,看到效果,再学习
步骤5:模仿和排错
步骤6:新建 springboot 项目
步骤7:pom.xml
步骤8:application.properties
步骤9:Application.java
步骤10:分页配置
步骤11:异常处理
步骤12:实体类
步骤13:Mapper
步骤14:Hero.xml
步骤15:Service 接口
步骤16:Service 实现类
步骤17:Controller 类
步骤18:js 文件
步骤19:模板文件
步骤20:启动测试

步骤 1 : 教程说明

这个教程比较复杂,涉及到了多方面的知识点,包括 Vue.js Springboot, Restful风格, 分页 PageHelper 的使用, Thymeleaf 模板。
对任何一个知识点不熟悉,都可以通过下载区(点击进入)搜索找到相关教程。

步骤 2 : 数据库准备

首先准备数据库 how2java

create database how2java

步骤 3 : 准备表

准备 Hero 表和相关数据

USE `how2java`;

CREATE TABLE `hero` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` varchar(30) DEFAULT NULL,

  `hp` float DEFAULT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=6194 DEFAULT CHARSET=utf8;

INSERT INTO `hero` VALUES (6094,'name0',0);

INSERT INTO `hero` VALUES (6095,'name1',1);

INSERT INTO `hero` VALUES (6096,'name2',2);

INSERT INTO `hero` VALUES (6097,'name3',3);

INSERT INTO `hero` VALUES (6098,'name4',4);

INSERT INTO `hero` VALUES (6099,'name5',5);

INSERT INTO `hero` VALUES (6100,'name6',6);

INSERT INTO `hero` VALUES (6101,'name7',7);

INSERT INTO `hero` VALUES (6102,'name8',8);

INSERT INTO `hero` VALUES (6103,'name9',9);

INSERT INTO `hero` VALUES (6104,'name10',10);

INSERT INTO `hero` VALUES (6105,'name11',11);

INSERT INTO `hero` VALUES (6106,'name12',12);

INSERT INTO `hero` VALUES (6107,'name13',13);

INSERT INTO `hero` VALUES (6108,'name14',14);

INSERT INTO `hero` VALUES (6109,'name15',15);

INSERT INTO `hero` VALUES (6110,'name16',16);

INSERT INTO `hero` VALUES (6111,'name17',17);

INSERT INTO `hero` VALUES (6112,'name18',18);

INSERT INTO `hero` VALUES (6113,'name19',19);

INSERT INTO `hero` VALUES (6114,'name20',20);

INSERT INTO `hero` VALUES (6115,'name21',21);

INSERT INTO `hero` VALUES (6116,'name22',22);

INSERT INTO `hero` VALUES (6117,'name23',23);

INSERT INTO `hero` VALUES (6118,'name24',24);

INSERT INTO `hero` VALUES (6119,'name25',25);

INSERT INTO `hero` VALUES (6120,'name26',26);

INSERT INTO `hero` VALUES (6121,'name27',27);

INSERT INTO `hero` VALUES (6122,'name28',28);

INSERT INTO `hero` VALUES (6123,'name29',29);

INSERT INTO `hero` VALUES (6124,'name30',30);

INSERT INTO `hero` VALUES (6125,'name31',31);

INSERT INTO `hero` VALUES (6126,'name32',32);

INSERT INTO `hero` VALUES (6127,'name33',33);

INSERT INTO `hero` VALUES (6128,'name34',34);

INSERT INTO `hero` VALUES (6129,'name35',35);

INSERT INTO `hero` VALUES (6130,'name36',36);

INSERT INTO `hero` VALUES (6131,'name37',37);

INSERT INTO `hero` VALUES (6132,'name38',38);

INSERT INTO `hero` VALUES (6133,'name39',39);

INSERT INTO `hero` VALUES (6134,'name40',40);

INSERT INTO `hero` VALUES (6135,'name41',41);

INSERT INTO `hero` VALUES (6136,'name42',42);

INSERT INTO `hero` VALUES (6137,'name43',43);

INSERT INTO `hero` VALUES (6138,'name44',44);

INSERT INTO `hero` VALUES (6139,'name45',45);

INSERT INTO `hero` VALUES (6140,'name46',46);

INSERT INTO `hero` VALUES (6141,'name47',47);

INSERT INTO `hero` VALUES (6142,'name48',48);

INSERT INTO `hero` VALUES (6143,'name49',49);

INSERT INTO `hero` VALUES (6144,'name50',50);

INSERT INTO `hero` VALUES (6145,'name51',51);

INSERT INTO `hero` VALUES (6146,'name52',52);

INSERT INTO `hero` VALUES (6147,'name53',53);

INSERT INTO `hero` VALUES (6148,'name54',54);

INSERT INTO `hero` VALUES (6149,'name55',55);

INSERT INTO `hero` VALUES (6150,'name56',56);

INSERT INTO `hero` VALUES (6151,'name57',57);

INSERT INTO `hero` VALUES (6152,'name58',58);

INSERT INTO `hero` VALUES (6153,'name59',59);

INSERT INTO `hero` VALUES (6154,'name60',60);

INSERT INTO `hero` VALUES (6155,'name61',61);

INSERT INTO `hero` VALUES (6156,'name62',62);

INSERT INTO `hero` VALUES (6157,'name63',63);

INSERT INTO `hero` VALUES (6158,'name64',64);

INSERT INTO `hero` VALUES (6159,'name65',65);

INSERT INTO `hero` VALUES (6160,'name66',66);

INSERT INTO `hero` VALUES (6161,'name67',67);

INSERT INTO `hero` VALUES (6162,'name68',68);

INSERT INTO `hero` VALUES (6163,'name69',69);

INSERT INTO `hero` VALUES (6164,'name70',70);

INSERT INTO `hero` VALUES (6165,'name71',71);

INSERT INTO `hero` VALUES (6166,'name72',72);

INSERT INTO `hero` VALUES (6167,'name73',73);

INSERT INTO `hero` VALUES (6168,'name74',74);

INSERT INTO `hero` VALUES (6169,'name75',75);

INSERT INTO `hero` VALUES (6170,'name76',76);

INSERT INTO `hero` VALUES (6171,'name77',77);

INSERT INTO `hero` VALUES (6172,'name78',78);

INSERT INTO `hero` VALUES (6173,'name79',79);

INSERT INTO `hero` VALUES (6174,'name80',80);

INSERT INTO `hero` VALUES (6175,'name81',81);

INSERT INTO `hero` VALUES (6176,'name82',82);

INSERT INTO `hero` VALUES (6177,'name83',83);

INSERT INTO `hero` VALUES (6178,'name84',84);

INSERT INTO `hero` VALUES (6179,'name85',85);

INSERT INTO `hero` VALUES (6180,'name86',86);

INSERT INTO `hero` VALUES (6181,'name87',87);

INSERT INTO `hero` VALUES (6182,'name88',88);

INSERT INTO `hero` VALUES (6183,'name89',89);

INSERT INTO `hero` VALUES (6184,'name90',90);

INSERT INTO `hero` VALUES (6185,'name91',91);

INSERT INTO `hero` VALUES (6186,'name92',92);

INSERT INTO `hero` VALUES (6187,'name93',93);

INSERT INTO `hero` VALUES (6188,'name94',94);

INSERT INTO `hero` VALUES (6189,'name95',95);

INSERT INTO `hero` VALUES (6190,'name96',96);

INSERT INTO `hero` VALUES (6191,'name97',97);

INSERT INTO `hero` VALUES (6192,'name98',98);

INSERT INTO `hero` VALUES (6193,'name99',99);

步骤 4 : 先运行,看到效果,再学习

老规矩,先下载下载区(点击进入)的可运行项目,配置运行起来,确认可用之后,再学习做了哪些步骤以达到这样的效果。
运行下面类的主方法启动项目

com.how2java.springboot.Application


然后访问测试地址:

http://127.0.0.1:8080/listHero


这就是前后端分离的 CRUD 了。
没有套用 bootstrap 美化界面,尽量要足够少的知识来展现本教程的核心内容,以免被分散精力。

先运行,看到效果,再学习

步骤 5 : 模仿和排错

在确保可运行项目能够正确无误地运行之后,再严格照着教程的步骤,对代码模仿一遍。
模仿过程难免代码有出入,导致无法得到期望的运行结果,此时此刻通过比较正确答案 ( 可运行项目 ) 和自己的代码,来定位问题所在。
采用这种方式,学习有效果,排错有效率,可以较为明显地提升学习速度,跨过学习路上的各个槛。

推荐使用diffmerge软件,进行文件夹比较。把你自己做的项目文件夹,和我的可运行项目文件夹进行比较。
这个软件很牛逼的,可以知道文件夹里哪两个文件不对,并且很明显地标记出来
这里提供了绿色安装和使用教程:diffmerge 下载和使用教程

步骤 6 : 新建 springboot 项目

新建一个 springboot 项目,新建方式在前面教程已经讲解过了,这里不赘述
Eclipse 方式创建 Springboot 项目
IDEA 方式创建 Springboot 项目

步骤 7 : pom.xml

pom.xml 中的相关导包,各个部分都做了注释

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

  <groupId>com.how2java</groupId>

  <artifactId>springboot</artifactId>

  <version>0.0.1-SNAPSHOT</version>

  <name>springboot</name>

  <description>springboot</description>

  <packaging>war</packaging>

   

    <parent>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-parent</artifactId>

        <version>1.5.9.RELEASE</version>

    </parent>

    <dependencies>

        <!-- springboot web -->

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-web</artifactId>

        </dependency>

        <!-- springboot tomcat 支持 -->

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-tomcat</artifactId>

        </dependency>

        <!-- thymeleaf -->

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-thymeleaf</artifactId>

        </dependency>

        <!-- thymeleaf legacyhtml5 模式支持 -->      

        <dependency>

            <groupId>net.sourceforge.nekohtml</groupId>

            <artifactId>nekohtml</artifactId>

            <version>1.9.22</version>

        </dependency>        

        <!-- 测试支持 -->

        <dependency>

              <groupId>junit</groupId>

              <artifactId>junit</artifactId>

              <version>3.8.1</version>

              <scope>test</scope>

        </dependency>

        <!-- 分页 -->

        <dependency>

            <groupId>com.github.pagehelper</groupId>

            <artifactId>pagehelper</artifactId>

            <version>4.1.6</version>

        </dependency>    

        <!-- mybatis -->

        <dependency>

            <groupId>org.mybatis.spring.boot</groupId>

            <artifactId>mybatis-spring-boot-starter</artifactId>

            <version>1.1.1</version>

        </dependency>        

        <!-- tomcat的支持.-->

        <dependency>

               <groupId>org.apache.tomcat.embed</groupId>

               <artifactId>tomcat-embed-jasper</artifactId>

        </dependency>    

        <!-- 热部署 -->

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-devtools</artifactId>

            <optional>true</optional>

        </dependency>

        <!-- mysql-->

        <dependency>

            <groupId>mysql</groupId>

            <artifactId>mysql-connector-java</artifactId>

            <version>5.1.21</version>

        </dependency>

    </dependencies>

    <properties>

        <java.version>1.8</java.version>

    </properties>

    <build>

        <plugins>

            <plugin>

                <groupId>org.springframework.boot</groupId>

                <artifactId>spring-boot-maven-plugin</artifactId>

            </plugin>

        </plugins>

    </build>

</project>

步骤 8 : application.properties

在 src/main/resources 下新建 application.properties 文件
配置文件指定了 数据库参数, mybatis 参数 和 thymeleaf 参数
其中 LEGACYHTML5 表示使用传统模式,比起 HTML5 来对 html的校验更宽松点,符合大家(懒散)的开发习惯。。。

application.properties

#database

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8

spring.datasource.username=root

spring.datasource.password=admin

spring.datasource.driver-class-name=com.mysql.jdbc.Driver

#mybatis

mybatis.mapper-locations=classpath:mapper/*.xml

mybatis.type-aliases-package=com.how2java.springboot.pojo

#thymeleaf

spring.thymeleaf.mode=LEGACYHTML5

spring.thymeleaf.encoding=UTF-8

spring.thymeleaf.content-type=text/html

spring.thymeleaf.cache=false

步骤 9 : Application.java

启动类

package com.how2java.springboot;

  

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

  

@SpringBootApplication

public class Application {

  

    public static void main(String[] args) {

        SpringApplication.run(Application.class, args);

    }

  

}

步骤 10 : 分页配置

package com.how2java.springboot.config;

  

import java.util.Properties;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import com.github.pagehelper.PageHelper;

  

@Configuration

public class PageHelperConfig {

  

    @Bean

    public PageHelper pageHelper() {

        PageHelper pageHelper = new PageHelper();

        Properties p = new Properties();

        p.setProperty("offsetAsPageNum""true");

        p.setProperty("rowBoundsWithCount""true");

        p.setProperty("reasonable""true");

        pageHelper.setProperties(p);

        return pageHelper;

    }

}

步骤 11 : 异常处理

package com.how2java.springboot.exception;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.bind.annotation.ControllerAdvice;

import org.springframework.web.bind.annotation.ExceptionHandler;

import org.springframework.web.servlet.ModelAndView;

@ControllerAdvice

public class GlobalExceptionHandler {

    @ExceptionHandler(value = Exception.class)

    public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {

        ModelAndView mav = new ModelAndView();

        mav.addObject("exception", e);

        mav.addObject("url", req.getRequestURL());

        mav.setViewName("errorPage");

        return mav;

    }

}

步骤 12 : 实体类

package com.how2java.springboot.pojo;

public class Hero {

    private int id;

     

    private String name;

    private int hp;

     

    public int getHp() {

        return hp;

    }

    public void setHp(int hp) {

        this.hp = hp;

    }

    public int getId() {

        return id;

    }

    public void setId(int id) {

        this.id = id;

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    @Override

    public String toString() {

        return "Hero [id=" + id + ", name=" + name + ", hp=" + hp + "]";

    }

}

步骤 13 : Mapper

package com.how2java.springboot.mapper;

  

import java.util.List;

import org.apache.ibatis.annotations.Mapper;

import com.how2java.springboot.pojo.Hero;

  

@Mapper

public interface HeroMapper {

    public int add(Hero hero);

     

    public void delete(int id);

         

    public Hero get(int id);

       

    public int update(Hero hero); 

         

    public List<Hero> list();

}

步骤 14 : Hero.xml

这个文件就放在 src/main/resources/mapper 目录下

Hero.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE mapper

    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

   

    <mapper namespace="com.how2java.springboot.mapper.HeroMapper">

        <insert id="add" parameterType="Hero" >

            insert into hero ( name,hp ) values (#{name},#{hp})  

        </insert>

          

        <delete id="delete" parameterType="Hero" >

            delete from hero where id= #{id} 

        </delete>

          

        <select id="get" parameterType="_int" resultType="Hero">

            select * from   hero  where id= #{id}  

        </select>

  

        <update id="update" parameterType="Hero" >

            update hero set name=#{name}, hp = #{hp} where id=#{id}  

        </update>

        <select id="list" resultType="Hero">

            select * from   hero    

        </select

    </mapper>

步骤 15 : Service 接口

package com.how2java.springboot.service;

import java.util.List;

import com.how2java.springboot.pojo.Hero;

public interface HeroService {

    public int add(Hero hero);

     

    public void delete(int id);

         

    public Hero get(int id);

       

    public int update(Hero hero); 

         

    public List<Hero> list();

}

步骤 16 : Service 实现类

package com.how2java.springboot.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import com.how2java.springboot.mapper.HeroMapper;

import com.how2java.springboot.pojo.Hero;

import com.how2java.springboot.service.HeroService;

@Service

public class HeroServiceImpl implements HeroService{

     

    @Autowired HeroMapper heroMapper;

    @Override

    public int add(Hero hero) {

        return heroMapper.add(hero);

    }

    @Override

    public void delete(int id) {

        heroMapper.delete(id);

    }

    @Override

    public Hero get(int id) {

        return heroMapper.get(id);

    }

    @Override

    public int update(Hero hero) {

        return heroMapper.update(hero);

    }

    @Override

    public List<Hero> list() {

        return heroMapper.list();

    }

}

步骤 17 : Controller 类

首先 HeroController 分为两部分:
1. restful 部分
2. 页面跳转部分

restful 就提供 CRUD 等等操作
页面跳转主要用来跳转到 thymeleaf 对应的 html 文件

package com.how2java.springboot.web;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.DeleteMapping;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.PutMapping;

import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.RestController;

import org.springframework.web.servlet.ModelAndView;

import com.github.pagehelper.PageHelper;

import com.github.pagehelper.PageInfo;

import com.how2java.springboot.pojo.Hero;

import com.how2java.springboot.service.HeroService;

  

@RestController

public class HeroController {

    @Autowired HeroService heroService;

     

    /*restful 部分*/

    @GetMapping("/heroes")

    public PageInfo<Hero> list(@RequestParam(value = "start", defaultValue = "1") int start,@RequestParam(value = "size", defaultValue = "5") int size) throws Exception {

        PageHelper.startPage(start,size,"id desc");

        List<Hero> hs=heroService.list();

        System.out.println(hs.size());

        PageInfo<Hero> page = new PageInfo<>(hs,5); //5表示导航分页最多有5个,像 [1,2,3,4,5] 这样

        return page;

    }

     

    @GetMapping("/heroes/{id}")

    public Hero get(@PathVariable("id") int id) throws Exception {

        System.out.println(id);

        Hero h=heroService.get(id);

        System.out.println(h);

        return h;

    }

     

    @PostMapping("/heroes")

    public String add(@RequestBody Hero h) throws Exception {

        heroService.add(h);

        return "success";

    }

    @DeleteMapping("/heroes/{id}")

    public String delete(Hero h) throws Exception {

        heroService.delete(h.getId());

        return "success";

    }

    @PutMapping("/heroes/{id}")

    public String update(@RequestBody Hero h) throws Exception {

        heroService.update(h);

        return "success";

    }

     

    /*页面跳转 部分*/

    @RequestMapping(value="/listHero", method=RequestMethod.GET)

    public ModelAndView listHero(){

        ModelAndView mv = new ModelAndView("listHero");

        return mv;

    }

     

    @RequestMapping(value="/editHero", method=RequestMethod.GET)

    public ModelAndView editHero(){

        ModelAndView mv = new ModelAndView("editHero");

        return mv;

    }   

}

步骤 18 : js 文件

在 src/main/webapp 下新建 js 目录,里面放上3个要用到的 第三方 js 库: axios.min.js, jquery.min.js, vue.min.js
这3个文件压缩了在下载区(点击进入)下载

js 文件

步骤 19 : 模板文件

在 resources 下新建 templates 目录,创建3个模板文件

模板文件

<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org">

<head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    <script src="./js/jquery.min.js"></script>

    <script src="./js/vue.min.js"></script>

    <script src="./js/axios.min.js"></script>   

    <style type="text/css">

        td{

            border:1px solid gray;

        }

           

        table{

            border-collapse:collapse;

        }

       

        div#app{

            margin:20px auto;

            width:400px;

            padding:20px;

        }     

         

        div#pagination{

            text-align: center;

            line-height: 100px;

        }

        div#pagination a{

            text-decoration:none;

        }

         

        .disableHref{

            cursor:default;

            color:#E5E0E0;

            text-decoration:none;       

        }

    </style>

    <script>

        $(function(){

            $("a.disableHref").click(function(event){

                return false;

//                event.preventDefault();

            });

        });

    </script>

</head>

   

<body>

    <div id="app">

            <table id="heroListTable" >

                    <tr>

                        <td colspan="3">

                            <div id="pagination" >

                                <a :class="{ disableHref: pagination.pageNum==1 }" href="#nowhere" @click="jump('first')">[first]</a>

                                <a :class="{ disableHref: !pagination.hasPreviousPage }" href="#nowhere" @click="jump('pre')">[pre]</a>

                                <a href="#nowhere" :class="{disableHref:pagination.pageNum==i}"  v-for="i in pagination.navigatepageNums" @click="jumpByNumber(i)" >

                                    {{i}}

                                </a>

                                <a :class="{ disableHref: !pagination.hasNextPage }" href="#nowhere" @click="jump('next')">[next]</a>

                                <a :class="{ disableHref: pagination.pageNum==pagination.pages }" href="#nowhere" @click="jump('last')">[last]</a>

                            </div>

                        </td>

                    </tr>

                                 

                    <tr>

                        <td>英雄名称</td>

                        <td>血量</td>

                        <td>操作</td>

                    </tr>

                    <tr v-for="hero in heros ">

                        <td>{{hero.name}}</td>

                        <td>{{hero.hp}}</td>

                        <td>

                            <a :href="'editHero?id=' + hero.id ">编辑</a>

                            <a href="#nowhere" @click="deleteHero(hero.id)">删除</a>

                        </td>

                    </tr>

                    <tr>

                        <td colspan="3">

                            <br>

                            英雄名称:

                            <input type="text"    v-model="hero4Add.name" />

                            <br>

                            血量:

                            <input type="number"    v-model="hero4Add.hp" />

                            <br>

                            <br>

                            <button type="button"  v-on:click="add">增加</button>

                            <br>

                         </td>                 

                    </tr>

                     

            </table>

    </div>

   

    <script type="text/javascript">

    var data4Vue = {

            heros: [],

            hero4Add: { id: 0, name: '', hp: '0'},

            pagination:{}

    };

    //ViewModel

    var vue = new Vue({

        el: '#app',

        data: data4Vue,

        mounted:function(){ //mounted 表示这个 Vue 对象加载成功了

            this.list(1);

        },       

        methods: {     

            list:function(start){

                var url = "heroes?start="+start;

                axios.get(url).then(function(response) {

                    vue.pagination = response.data;

                    console.log(vue.pagination);

                    vue.heros = response.data.list;

                })    

            },         

            add: function (event) {

                var url = "heroes";

                 

                axios.post(url,this.hero4Add).then(function(response){

                    vue.list(1);

                    vue.hero4Add = { id: 0, name: '', hp: '0'}

                });

            },

            deleteHero: function (id) {

                var url = "heroes/"+id;

                axios.delete(url).then(function(response){

                    vue.list(1);

                });

            },

            jump: function(page){

                if('first'== page && 1!=vue.pagination.pageNum)

                    vue.list(1);

                 

                else if('pre'== page && vue.pagination.hasPreviousPage )

                    vue.list(vue.pagination.prePage);

                 

                else if('next'== page && vue.pagination.hasNextPage)

                    vue.list(vue.pagination.nextPage);                 

                 

                else if('last'== page && vue.pagination.pageNum!=vue.pagination.pages)

                    vue.list(vue.pagination.pages);

                 

            },

            jumpByNumber: function(start){

                if(start!=vue.pagination.pageNum)

                    vue.list(start);

            }

        }

    });

    </script>

</body>

</html>

        

<!DOCTYPE html>

<html xmlns:th="http://www.thymeleaf.org">

<head>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    <script src="./js/jquery.min.js"></script>

    <script src="./js/vue.min.js"></script>

    <script src="./js/axios.min.js"></script>   

    <style type="text/css">

        div#app{

            margin:20px auto;

            width:400px;

            padding:20px;

        }     

    </style>

</head>

   

<body>

    <div id="app">

            <div id="div4Update">

               

                            英雄名称:

                            <input type="text"    v-model="hero4Update.name" />

                            <br>

                            血量:

                            <input type="number"    v-model="hero4Update.hp" />                      

                            <input type="hidden"    v-model="hero4Update.id" />                      

                            <br>

                            <button type="button"  v-on:click="update">修改</button>               

                            <button type="button"  v-on:click="cancel">取消</button>               

               

            </div>

    </div>

   

    <script type="text/javascript">

    //获取地址栏参数的函数

    function getUrlParms(name){

           var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");

           var r = window.location.search.substr(1).match(reg);

           if(r!=null)

               return unescape(r[2]);

           return null;

    }

     

    var data4Vue = {

            heros: [],

            hero4Update: { id: 0, name: '', hp: '0'}

    };     

     

    //ViewModel

    var vue = new Vue({

        el: '#app',

        data: data4Vue,

        mounted:function(){ //mounted 表示这个 Vue 对象加载成功了

            this.get();

        },       

        methods: {

            get:function(){

                var id = getUrlParms("id");

                var url = "heroes/"+id;

                console.log(url);

                axios.get(url).then(function(response) {

                    vue.hero4Update = response.data;

                })    

            },

            update:function (event) {

                var url = "heroes/"+vue.hero4Update.id;

                axios.put(url,vue.hero4Update).then(function(response){

                    location.href="listHero";

                });

            },

            cancel:function(){

                location.href="listHero";

            }

        }

    });

    </script>

</body>

</html>

    

<html xmlns:th="http://www.thymeleaf.org">

<body>

    <div style="width:500px;border:1px solid lightgray;margin:200px auto;padding:80px">

        系统 出现了异常,异常原因是:

        <div th:text="${exception}"></div>

        出现异常的地址是:

        <div th:text="${url}"></div>

    </div>

</body>

</html>

步骤 20 : 启动测试

运行下面类的主方法启动项目

com.how2java.springboot.Application


然后访问测试地址:

http://127.0.0.1:8080/listHero


这就是前后端分离的 CRUD 了。
没有套用 bootstrap 美化界面,尽量要足够少的知识来展现本教程的核心内容,以免被分散精力。

启动测试


更多内容,点击了解: https://how2j.cn/k/springboot/springboot-vue/1788.html

  • 17
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以使用 Spring Boot + Vue + Webpack 来实现前后端分离的框架,具体代码如下:Spring Boot:<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>Vue:<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>Webpack:const path = require('path'); const webpack = require('webpack');module.exports = { entry: './src/js/app.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }, plugins: [ new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }) ] }; ### 回答2: 要实现Spring BootVue前后端分离,可以使用以下具体的框架和代码: 1. 后端使用Spring Boot框架实现RESTful API: - 创建一个Spring Boot项目,添加所需的依赖(如Spring Web、Spring Data JPA等)。 - 在项目中创建一个Controller类,使用`@RestController`注解标记。 - 编写各个API接口对应的方法,并使用`@RequestMapping`等注解进行路由映射。 - 可以使用Spring Data JPA来简化数据库操作,创建实体类和对应的Repository接口。 - 通过`@CrossOrigin`注解允许跨域请求。 2. 前端使用Vue框架实现单页应用: - 创建一个Vue项目,可以使用Vue CLI工具进行脚手架搭建。 - 在项目中创建相应的组件,用于展示数据和处理用户交互。 - 使用Vue Router进行前端路由管理。 - 使用Axios库进行前后端数据交互,发送HTTP请求获取后端API返回的数据。 - 使用Vue的生命周期钩子函数和Vue的数据绑定特性来处理页面逻辑。 3. 连接前后端: - 在Vue的组件中使用Axios发送请求到后端API。 - 接收后端返回的数据,并在页面上进行展示。 - 在触发某些事件时,调用Axios发送请求到后端API来更新数据。 这样,就可以实现前后端分离的架构。后端通过Spring Boot框架提供RESTful API,前端使用Vue框架构建单页应用,并通过Axios库发送HTTP请求和后端进行数据交互。通过这种方式,前后端可以独立开发和部署,提高了开发效率和灵活性。 ### 回答3: 要实现Spring BootVue前后端分离,可以采用以下具体的框架和代码实现。 1. 后端框架:Spring Boot Spring Boot是一种用于构建独立的、基于SpringJava应用程序的框架。它可以简化Spring应用程序的配置和部署,并提供了可集成的开发和测试工具。使用Spring Boot可以快速搭建后端API服务。 2. 前端框架:Vue.js Vue.js是一种用于构建用户界面的JavaScript框架,它可以实现响应式的数据绑定和组件化的开发Vue.js使用简洁的语法和强大的生态系统,使得前端开发更加高效和可维护。 3. 框架整合 在实现前后端分离的过程中,可以通过Restful API进行前后端数据交互。后端使用Spring Boot提供API接口,前端使用Vue.js发起HTTP请求获取数据。 典型的框架代码结构如下: - 后端代码结构 - src/main/java - com.example.demo - controller - UserController.java:定义用户相关的API接口,处理HTTP请求。 - model - User.java:定义用户类,包含用户的属性和方法。 - service - UserService.java:定义用户相关的业务逻辑,如用户的增删改查。 - UserServiceImpl.java:实现UserService接口的具体逻辑。 - repository - UserRepository.java:定义用户数据的访问方式,如数据库操作。 - src/main/resources - application.properties:配置Spring Boot应用的相关属性。 - 前端代码结构 - src - components - UserList.vue:用户列表组件,展示后端返回的用户数据。 - views - User.vue:用户界面,包含用户的增删改查等操作。 - router - index.js:前端路由配置文件,定义前端路由和页面的映射关系。 - App.vue:根组件,包含整个前端应用的布局和共享逻辑。 - main.js:入口文件,初始化Vue应用。 以上是一个简单的示例,可以根据实际需求和复杂程度进行相应的调整。通过Spring Boot提供API接口,Vue.js发起HTTP请求获取数据,实现了前后端分离开发模式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值