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日

相关文章

  • vue3中各种类型文件进行预览功能实例

    我将为您详细讲解“Vue3中各种类型文件进行预览功能实例”的攻略。 一、问题背景 在Vue3中,如何实现对各种类型文件进行预览功能?比如图片、音频、视频等类型的文件。 二、解决方案 Vue3中可以使用第三方库来实现文件预览功能,其中比较常用的有以下几种: viewerjs:适用于图片、PDF、音频和视频等各种类型的文件预览。 vue-plyr:一个视频和音频…

    Vue 2023年5月28日
    00
  • JavaScript实现浅拷贝与深拷贝的方法分析

    当我们需要在JavaScript中复制对象时,我们通常会使用浅拷贝或深拷贝,这两种方法可以实现不同程度的对象复制。下面是实现浅拷贝和深拷贝的方法分析: 实现 JavaScript 浅拷贝的方法 JavaScript中使用浅拷贝来复制对象,只是复制了对象的引用,因此,这个新创建的对象和旧对象指向相同的内存地址。这意味着,如果我们修改新对象中的某个属性,则旧对象…

    Vue 2023年5月28日
    00
  • 快速了解Vue父子组件传值以及父调子方法、子调父方法

    快速了解Vue父子组件传值以及父调子方法、子调父方法 在Vue中,组件通常会通过props属性传递数据,也可以使用$emit方法触发自定义事件来实现父调子方法和子调父方法。 父子组件传值 通过props属性传递数据 在父组件中使用props属性传递数据,子组件中使用props接收数据。比如: <!– 父组件 –> <template&g…

    Vue 2023年5月28日
    00
  • Vue cli及Vue router实例详解

    Vue cli及Vue router实例详解 什么是Vue cli? Vue cli是一个构建Vue.js项目的基础工具。通过Vue cli可以创建一个基本的Vue.js项目,它包含了一些常用的插件和配置,可以优化我们的开发体验。Vue cli本身还提供了一些命令行工具来帮助我们快速创建组件、安装插件等操作。 如何安装Vue cli? 在开始使用Vue cl…

    Vue 2023年5月28日
    00
  • Vue实现在线预览pdf文件功能(利用pdf.js/iframe/embed)

    下面我将为你详细讲解如何用Vue实现在线预览pdf文件功能,对应的技术包括pdf.js、iframe、embed等。 1. 准备工作 首先,需要下载pdf.js(官网地址)并引入到Vue项目中。在main.js中引入如下: import pdfjsLib from ‘pdfjs-dist/build/pdf’; import pdfWorker from ‘…

    Vue 2023年5月28日
    00
  • 用v-html解决Vue.js渲染中html标签不被解析的问题

    使用Vue.js时,如果在模板中绑定含有HTML标签的数据时,Vue.js会默认将其转义为纯文本,防止XSS攻击。有时候,开发者想要渲染出真正的HTML标签,就需要使用v-html指令。 以下是使用v-html指令解决Vue.js渲染中HTML标签不被解析的问题的攻略: 步骤一:在模板中使用v-html指令 在Vue.js的模板中使用v-html指令来解决H…

    Vue 2023年5月27日
    00
  • 使用webpack手动搭建vue项目的步骤

    使用webpack手动搭建vue项目的步骤可能有点繁琐,但却是从根本上了解vue和webpack的运行机制、优化和调试的重要一步。 以下是手动搭建vue项目的完整攻略: 步骤1:新建项目 首先,我们需要在本地新建一个项目文件夹并打开命令行,使用npm初始化项目: npm init 这将在项目文件夹中创建一个package.json文件,其中包含了我们需要的依…

    Vue 2023年5月28日
    00
  • vue路由分文件拆分管理详解

    下面我来详细讲解“Vue路由分文件拆分管理详解”的攻略。 什么是Vue路由分文件拆分管理? Vue路由分文件拆分管理,是指将Vue的路由配置放在不同的文件中进行拆分,从而使路由配置更加清晰明了,方便维护和管理。 Vue路由分文件拆分管理的优点 代码结构更加清晰明了,便于维护和管理; 大大提高了开发效率,减少了错误概率; 路由的修改和新增更加方便和快捷; 路由…

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