SpringBoot+VUE实现前后端分离的实战记录

下面是“SpringBoot+VUE实现前后端分离的实战记录”的完整攻略:

1. 前后端分离理念

前后端分离(Front-end and back-end separation)是指前端页面和后端数据完成分离,前端专注于数据的呈现,后端专注于数据的处理、存取。

2. 技术栈介绍

  • 前端技术:Vue、Vue-router、Vuex、Axios、Element UI等
  • 后端技术:SpringBoot、MyBatis、MySQL、Maven等

3. 前端项目搭建

3.1 安装Vue-cli3

首先安装Vue-cli3,可参考官网或下列示例命令生成基于webpack的模板项目:

vue create my-project

3.2 安装必要依赖

然后我们安装一些必要的依赖:

npm install vue-router vuex axios element-ui --save
  • vue-router:路由管理
  • vuex:全局状态管理
  • axios:基于Promise的HTTP库
  • element-ui:基于Vue2.0的UI组件库

3.3 创建页面和组件

接下来我们创建Vue页面和组件。

示例一:创建一个简单的登录页面

<!-- Login.vue -->
<template>
  <div>
    <h1>用户登录</h1>
    <el-form ref="form" :model="form" label-width="80px">
      <el-form-item label="用户名" prop="username">
        <el-input v-model="form.username"></el-input>
      </el-form-item>
      <el-form-item label="密码" prop="password">
        <el-input type="password" v-model="form.password"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="handleSubmit">登录</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  data() {
    return {
      form: {
        username: '',
        password: ''
      }
    }
  },
  methods: {
    handleSubmit() {
      // 处理登录逻辑
    }
  }
}
</script>

示例二:创建一个通用的分页组件

<!-- Pagination.vue -->
<template>
  <el-pagination layout="total, prev, pager, next, jumper"
                  :total="total"
                  :page-size="pageSize"
                  :current-page="currentPage"
                  @current-change="handleCurrentChange">
  </el-pagination>
</template>

<script>
export default {
  props: {
    total: {
      type: Number,
      default: 0
    },
    pageSize: {
      type: Number,
      default: 10
    },
    currentPage: {
      type: Number,
      default: 1
    }
  },
  methods: {
    handleCurrentChange(currentPage) {
      // 处理当前页码改变逻辑
    }
  }
}
</script>

4. 后端项目搭建

4.1 创建SpringBoot项目

最简单的方式是使用Spring Initializr创建一个SpringBoot项目,包含必要依赖:Spring Web、MyBatis等。

4.2 数据库设计和建表

示例一:用户表

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `username` varchar(50) NOT NULL COMMENT '用户名',
  `password` varchar(50) NOT NULL COMMENT '密码',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='用户表'

示例二:文章表

CREATE TABLE `article` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `title` varchar(200) NOT NULL COMMENT '标题',
  `content` text NOT NULL COMMENT '内容',
  `gmt_create` datetime NOT NULL COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='文章表'

4.3 数据库配置和MyBatis映射

根据不同的数据库类型和数据库连接方式对/resources文件夹下的application.propertiesMyBatis相关XML进行配置。

示例一:application.properties

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root

示例二:Mapper示例

<!-- UserMapper -->
@Mapper
public interface UserMapper {
  @Select("SELECT * FROM user WHERE username=#{username} AND password=#{password}")
  User selectByUsernameAndPassword(@Param("username") String username, @Param("password") String password);
}

<!-- ArticleMapper -->
@Mapper
public interface ArticleMapper {
  @Select("SELECT COUNT(*) FROM article")
  int selectTotalCount();

  @Select("SELECT * FROM article ORDER BY gmt_modified DESC LIMIT #{offset},#{limit}")
  List<Article> selectPage(@Param("offset") int offset, @Param("limit") int limit);
}

4.4 编写Controller和Service

示例一:登录逻辑Controller

// UserController
@RestController
@RequestMapping("/api")
public class UserController {
  @Autowired
  private UserService userService;

  @PostMapping("/login")
  public Result login(@RequestBody LoginForm form) {
    User user = userService.login(form.getUsername(), form.getPassword());
    if (user == null) {
      return Result.error("用户名或密码错误");
    }
    return Result.success(user, "登录成功");
  }
}

// UserService
@Service
@Transactional
public class UserService {
  @Autowired
  private UserMapper userMapper;

  public User login(String username, String password) {
    return userMapper.selectByUsernameAndPassword(username, password);
  }
}

示例二:分页查询逻辑Controller

// ArticleController
@RestController
@RequestMapping("/api")
public class ArticleController {
  @Autowired
  private ArticleService articleService;

  @GetMapping("/articles")
  public Result getArticlePage(@RequestParam(defaultValue="1") int page) {
    int totalCount = articleService.getTotalCount();
    int limit = 10;
    int offset = (page - 1) * limit;
    List<Article> articles = articleService.getPage(offset, limit);

    return Result.success(new Page<Article>(totalCount, articles), "查询成功");
  }
}

// ArticleService
@Service
@Transactional
public class ArticleService {
  @Autowired
  private ArticleMapper articleMapper;

  public int getTotalCount() {
    return articleMapper.selectTotalCount();
  }

  public List<Article> getPage(int offset, int limit) {
    return articleMapper.selectPage(offset, limit);
  }
}

5. 前后端联调

前后端联调分为两部分:

  1. 前端调用后端接口
  2. 后端提供数据供前端使用

5.1 前端调用后端接口

在前端项目中使用axios调用后端接口。

示例一:登录接口调用

// api.js
import axios from 'axios';

const baseUrl = 'http://localhost:8080/api';

export function login(username, password) {
  const url = `${baseUrl}/login`;
  const data = {
    username: username,
    password: password
  };
  return axios.post(url, data);
}

// LoginPage.vue
import { login } from '@/api';

export default {
  methods: {
    handleSubmit() {
      login(this.form.username, this.form.password).then(res => {
        // 成功回调
      }).catch(err => {
        // 失败回调
      });
    }
  }
}

示例二:分页查询接口调用

// api.js
import axios from 'axios';

const baseUrl = 'http://localhost:8080/api';

export function getArticlePage(page = 1) {
  const url = `${baseUrl}/articles?page=${page}`;
  return axios.get(url);
}

// ArticleListPage.vue
import Pagination from '@/components/Pagination';
import { getArticlePage } from '@/api';

export default {
  data() {
    return {
      articles: [],
      total: 0,
      currentPage: 1
    }
  },
  components: {
    Pagination
  },
  methods: {
    handleCurrentPageChange(currentPage) {
      this.currentPage = currentPage;
      this.refreshArticles();
    },
    refreshArticles() {
      getArticlePage(this.currentPage).then(res => {
        this.articles = res.data.data.list;
        this.total = res.data.data.total;
      });
    }
  },
  created() {
    this.refreshArticles();
  }
}

5.2 后端提供数据

后端通过Controller提供JSON格式的数据。

示例一:成功返回示例

{
  "code": 200,
  "data": {
    "id": 1,
    "username": "guest",
    "password": "123456"
  },
  "message": "登录成功"
}

示例二:失败返回示例

{
  "code": 500,
  "message": "用户名或密码错误"
}

6. 总结

以上就是本文介绍的基于SpringBoot和Vue的前后端分离开发实践。前端专注于数据的呈现,后端则专注于数据的处理和存储。总的来说,前后端分离的开发模式能够提高开发效率,提升网站性能,体验也更佳。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot+VUE实现前后端分离的实战记录 - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • vue结合Axios+v-for列表循环实现网易健康页面(实例代码)

    下面是详细讲解“vue结合Axios+v-for列表循环实现网易健康页面(实例代码)”的完整攻略: 一、环境配置 首先,我们需要在本地环境中安装Vue.js和Axios。可以通过以下命令进行安装: npm install vue axios –save-dev 接下来,在Vue的入口文件中引入Axios: // main.js import Vue fro…

    Vue 2023年5月28日
    00
  • vue中filters 传入两个参数 / 使用两个filters的实现方法

    在 Vue 中,可以使用 filter 过滤器来处理模板中的数据。filter 在显示数据之前对其进行处理,比如对字符串格式化、将时间格式化等等。 在 Vue 中,我们可以定义一个 filter 来处理一些数据,此时这个 filter 就是一个全局的 filter。可以被任何组件进行调用。 现在我们来详细讲解“vue中filters 传入两个参数 / 使用两…

    Vue 2023年5月27日
    00
  • Vue.js实现日历功能

    Vue.js是一个流行的JavaScript框架,可以帮助我们构建优秀的Web应用程序。在本文中,我将展示如何使用Vue.js来实现一个简单的日历功能。以下是完整攻略: 步骤一:安装和创建项目 首先,我们需要安装Vue.js,可以使用npm或yarn进行安装。在安装完成之后,我们将创建一个项目。可以使用Vue CLI进行项目初始化: vue create m…

    Vue 2023年5月29日
    00
  • ES6中的class是如何实现的(附Babel编译的ES5代码详解)

    下面是详细讲解 “ES6中的class是如何实现的(附Babel编译的ES5代码详解)” 的攻略。 前言 ES6中的class是一种新的语法糖,它提供了一种更简单、更语义化的方式来声明类,让编写面向对象代码更加方便。本文将介绍class的语法和原理,并附上Babel编译后的ES5代码做详解。 class语法 首先我们来看一下class的语法: class P…

    Vue 2023年5月28日
    00
  • vue页面使用多个定时器的方法

    下面是关于Vue页面使用多个定时器的方法的详细攻略: 一、前置知识 在使用Vue页面多个定时器之前,需要掌握以下知识: Vue.js的生命周期钩子函数:created、mounted、updated、destroyed setInterval和clearInterval的用法 二、方法一:使用Vue.js的watch属性 如果在Vue组件中同时使用多个定时器…

    Vue 2023年5月29日
    00
  • 关于Vue中axios的封装实例详解

    下面我将为你详细讲解关于Vue中axios的封装实例详解。 1. axios是什么? axios是一个基于Promise的HTTP客户端,用于浏览器和node.js的请求发送。它可以用于简单地进行HTTP请求,也可以进行拦截请求和响应,转换请求和响应数据,取消请求等操作。 2. axios的优点 基于Promise,易于使用 支持拦截请求和响应 支持转换请求…

    Vue 2023年5月29日
    00
  • js前端对于大量数据的展示方式及处理方法

    针对JavaScript前端对于大量数据的展示方式及处理方法,我们可以有以下攻略: 一、数据的分页处理 在面对大量的数据时,我们需要将其分页显示。这样可以减轻前端页面的压力,缩短数据的加载时间。一般情况下,我们将数据按照每页显示的个数进行分页处理,在页面中显示出分页器和分页数据。 示例 我们可以使用Vue.js和Vue-cli进行示例说明。首先,我们需要安装…

    Vue 2023年5月28日
    00
  • Vue watch中监听值的变化,判断后修改值方式

    当需要在Vue组件中监听某个特定数据的变化时,就需要用到Vue的watch功能。下面,我将为您详细讲解“Vue watch中监听值的变化,判断后修改值方式”的完整攻略。 监听数据变化 使用Vue的watch功能时,我们可以在组件中使用$watch来监听特定数据的变化,并在数据变化时执行相应的逻辑操作。 下面是一个示例,我们监听一个数据值dataValue的变…

    Vue 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部