我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Spring Boot和Vue前后端分离项目架构的全过程

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Spring Boot和Vue前后端分离项目架构的全过程

Spring Boot+Vue 前后端分离项目架构

项目流程:

1. SpringBoot 后端项目

1、新建一个 SpringBoot 工程,并添加项目开发过程中需要的相关依赖;

2、数据库新建 book 数据表;

-- ----------------------------
-- Table structure for book
-- ----------------------------
DROP TABLE IF EXISTS `book`;
CREATE TABLE `book`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `title` varchar(55) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `publish` varchar(55) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `authors` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `createTime` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
  `updateTime` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0),
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 14 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of book
-- ----------------------------
INSERT INTO `book` VALUES (2, '数据结构', '浙江出版社', '严威', '2022-03-18 14:38:22', '2022-03-18 14:38:25');
INSERT INTO `book` VALUES (5, '计算机组成原理', '机械工业出版社', '唐朔飞', '2022-03-14 14:38:28', '2022-03-15 14:38:36');
INSERT INTO `book` VALUES (6, '机器学习', '人民邮电出版社', '周志华', '2022-03-16 14:38:41', '2022-03-16 14:38:45');
INSERT INTO `book` VALUES (7, '图论及其应用', '科学技术出版社', '徐俊明', '2022-03-03 14:38:49', '2022-03-18 18:33:57');
INSERT INTO `book` VALUES (8, '推荐系统开发实战', '电子工业出版社', '高团阳', '2022-03-14 14:38:57', '2022-03-16 14:39:02');
INSERT INTO `book` VALUES (9, '大数据导论', '机械工业出版社', '曾诚', '2022-03-10 14:39:06', '2022-03-12 14:39:09');
INSERT INTO `book` VALUES (13, 'Java从零基础到实战', '中国工信出版集团', '宁楠', '2022-03-18 17:05:18', '2022-03-18 17:05:18');

3、application.yml 配置数据源和项目启动的端口号;

# 修改服务启动的端口
server:
  port: 8181
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/book?useUnicode=true&characterEncoding=UTF-8
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
# 配置日志,打印执行的sql语句
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

项目整体的目录结构如下:

4、创建实体类 Book.java;

@AllArgsConstructor
@NoArgsConstructor
@Data
@TableName(value = "book")
public class Book {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String title;
    private String publish;
    private String authors;

    @TableField(value = "createTime", fill = FieldFill.INSERT)
    private Date createTime;
    @TableField(value = "updateTime", fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
}

5、添加 MyBatis Plus 自动填充的处理器 config/DataHandler.java;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class DataHandler implements MetaObjectHandler{
    //插入时的填充策略
    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createTime", new Date(), metaObject);
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }
    //更新时的填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }
}

6、持久化层 mapper/BookMapper.java;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.trainingl.entity.Book;
import org.springframework.stereotype.Repository;

@Repository  //持久层注解
public interface BookMapper extends BaseMapper<Book> {
    //所有的CRUD操作都已经编写好了
}

7、服务层 service;

service/BookService.java

import com.trainingl.entity.Book;
import java.util.List;

//数据的增删改查接口
public interface BookService {
    public List<Book> findAll();
    public Book findById(Long id);
    public int insert(Book book);
    public int deleteById(Long id);
    public int updateById(Book book);
}

service/Impl/BookServiceImpl.java

import com.trainingl.entity.Book;
import com.trainingl.mapper.BookMapper;
import com.trainingl.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class BookServiceImpl implements BookService {
    @Autowired
    private BookMapper bookMapper;
    @Override
    public List<Book> findAll() {
        //查询搜索记录
        return bookMapper.selectList(null);
    }

    @Override
    public Book findById(Long id) {
        return bookMapper.selectById(id);
    }

    @Override
    public int insert(Book book) {
        return bookMapper.insert(book);
    }

    @Override
    public int deleteById(Long id) {
        return bookMapper.deleteById(id);
    }

    @Override
    public int updateById(Book book) {
        return bookMapper.updateById(book);
    }
}

8、控制层 Controller;

controller/BookController.java

import com.trainingl.entity.Book;
import com.trainingl.service.BookService;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@CrossOrigin  //跨域注解
public class BookController {
    @Autowired
    private BookService bookService;

    @RequestMapping("/booklist")
    public List<Book> booklist(){
        return bookService.findAll();
    }

    @RequestMapping("/addbook")
    public int addbook(@RequestBody Book book){
        return bookService.insert(book);
    }

    @DeleteMapping("/deleteById/{id}")
    public int deleteById(@PathVariable("id") Long id){
        Integer result = 0;
        result = bookService.deleteById(id);
        //删除成功则返回受影响的行数
        return result;
    }

    @GetMapping("/findById/{id}")
    public Book findById(@PathVariable("id") Long id){
        return bookService.findById(id);
    }

    @PutMapping("/updateById")
    public int updateById(@RequestBody Book book){
        //返回修改的条数
        return bookService.updateById(book);
    }

}

2. Vue 前端项目

1、主页面 App.vue

<template>
    <div id="app">
        <router-view/>
    </div>
</template>

<script>
    export default {
        name: 'App',
        components: {
        },
        data(){
            return{
            }
        },

    }
</script>

2、数据列表视图 views/table.vue

<template>
    <div>
        <el-table
                :data="tableData"
                border
                style="width: 70%">
            <el-table-column
                    fixed
                    prop="id"
                    label="编号"
                    width="80">
            </el-table-column>
            <el-table-column
                    prop="title"
                    label="书籍名称"
                    width="160">
            </el-table-column>
            <el-table-column
                    prop="publish"
                    label="出版社"
                    width="150">
            </el-table-column>
            <el-table-column
                    prop="authors"
                    label="作者"
                    width="120">
            </el-table-column>
            <el-table-column
                    prop="createTime"
                    label="创建时间"
                    width="150">
            </el-table-column>
            <el-table-column
                    prop="updateTime"
                    label="修改时间"
                    width="150">
            </el-table-column>
            <el-table-column
                    fixed="right"
                    label="操作"
                    width="150">
                <template slot-scope="scope">
                    <el-button @click="del(scope.row)" type="danger" size="small">删除</el-button>
                    <el-button @click="edit(scope.row)" type="success" size="small">编辑</el-button>
                </template>
            </el-table-column>
        </el-table>
        <el-button type="primary" @click="addBook" icon="el-icon-edit" size="small">添加记录</el-button>
    </div>
</template>

<script>
    export default {
        name: "table",
        methods: {
            addBook(){
                this.$router.push("/addbook")
            },
            del(row) {
                let _this = this;

                this.$confirm('此操作将永久删除该记录, 是否继续?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    this.$axios.delete("http://localhost:8181/deleteById/" + row.id).then(function (response) {
                        if (response.data == 1) {
                            //刷新页面
                            location.reload();
                        } else {
                            _this.$message({
                                showClose: true,
                                message: '删除信息失败!',
                                type: 'danger'
                            });
                        }
                    })
                })
            },
            edit(row) {
                this.$router.push("/edit?id=" + row.id);
            }
        },

        data() {
            return {
                tableData: []
            }
        },
        created(){
            let _this = this;
            this.$axios.get("http://localhost:8181/booklist").then(function (response) {
                _this.tableData = response.data;
            })
        }

    }
</script>

<style scoped>
</style>

3、新增视图文件 views/addBook.vue

<template>
    <div>
        <h2 style="padding-left: 200px">新增图书信息</h2>
        <el-form :model="ruleForm" style="width: 500px;" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
            <el-form-item label="书籍名称" prop="title">
                <el-input type="text" v-model="ruleForm.title" autocomplete="off"></el-input>
            </el-form-item>
            <el-form-item label="出版社" prop="publish">
                <el-input type="text" v-model="ruleForm.publish" autocomplete="off"></el-input>
            </el-form-item>
            <el-form-item label="作者信息" prop="authors">
                <el-input v-model.number="ruleForm.authors"></el-input>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
                <el-button @click="resetForm('ruleForm')">重置</el-button>
            </el-form-item>
        </el-form>
    </div>
</template>

<script>
    export default {
        name: "addBook",
        data() {
            var checkAuthor = (rule, value, callback) => {
                if (value === '') {
                    callback(new Error('请输入作者信息'));
                } else {
                    callback();
                }
            };
            var validateTitle = (rule, value, callback) => {
                if (value === '') {
                    callback(new Error('请输入书籍名称'));
                } else {
                    callback();
                }
            };
            var validatePublish = (rule, value, callback) => {
                if (value === '') {
                    callback(new Error('请输入出版社'));
                } else {
                    callback();
                }
            };
            return {
                ruleForm: {
                    title: '',
                    publish: '',
                    authors: ''
                },
                rules: {
                    title: [
                        { validator: validateTitle, trigger: 'blur' }
                    ],
                    publish: [
                        { validator: validatePublish, trigger: 'blur' }
                    ],
                    authors: [
                        { validator: checkAuthor, trigger: 'blur' }
                    ]
                }
            };
        },
        methods: {
            submitForm(formName) {
                let _this = this;
                this.$refs[formName].validate((valid) => {
                    if (valid) {
                        this.$axios.post("http://localhost:8181/addbook", _this.ruleForm).then(function (response) {
                            if(response.data == 1){
                                //跳转到表格页面
                                _this.$router.push('/table')
                            }
                        })
                    } else {
                        console.log('error submit!!');
                        return false;
                    }
                });
            },
            resetForm(formName) {
                this.$refs[formName].resetFields();
            }
        }
    }
</script>

<style scoped>
</style>

4、编辑或修改视图文件 views/edit.vue

<template>
    <div>
        <h2 style="padding-left: 200px">修改图书信息</h2>
        <el-form :model="ruleForm" style="width: 500px;" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
            <el-form-item label="图书编号">
                <el-input type="text" readonly  v-model="ruleForm.id" autocomplete="off"></el-input>
            </el-form-item>
            <el-form-item label="书籍名称" prop="title">
                <el-input type="text" v-model="ruleForm.title" autocomplete="off"></el-input>
            </el-form-item>
            <el-form-item label="出版社" prop="publish">
                <el-input type="text" v-model="ruleForm.publish" autocomplete="off"></el-input>
            </el-form-item>
            <el-form-item label="作者信息" prop="authors">
                <el-input v-model.number="ruleForm.authors"></el-input>
            </el-form-item>
            <el-form-item label="创建时间">
                <el-input readonly v-model.number="ruleForm.createTime"></el-input>
            </el-form-item>
            <el-form-item label="修改时间">
                <el-input readonly v-model.number="ruleForm.updateTime"></el-input>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
                <el-button @click="resetForm('ruleForm')">重置</el-button>
            </el-form-item>
        </el-form>
    </div>
</template>

<script>
    export default {
        name: "edit",
        data() {
            var checkAuthor = (rule, value, callback) => {
                if (value === '') {
                    callback(new Error('请输入作者信息'));
                } else {
                    callback();
                }
            };
            var validateTitle = (rule, value, callback) => {
                if (value === '') {
                    callback(new Error('请输入书籍名称'));
                } else {
                    callback();
                }
            };
            var validatePublish = (rule, value, callback) => {
                if (value === '') {
                    callback(new Error('请输入出版社'));
                } else {
                    callback();
                }
            };
            return {
                ruleForm: {
                    id: '',
                    title: '',
                    publish: '',
                    authors: '',
                    createTime: '',
                    updateTime: ''
                },
                rules: {
                    title: [
                        { validator: validateTitle, trigger: 'blur' }
                    ],
                    publish: [
                        { validator: validatePublish, trigger: 'blur' }
                    ],
                    authors: [
                        { validator: checkAuthor, trigger: 'blur' }
                    ]
                }
            };
        },
        methods: {
            submitForm(formName) {
                let _this = this;
                this.$refs[formName].validate((valid) => {
                    if (valid) {
                        this.$axios.put("http://localhost:8181/updateById", _this.ruleForm).then(function (response) {
                            if(response.data === 1){
                                //跳转到表格页面
                                _this.$router.push('/table')
                            }
                        })
                    } else {
                        console.log('error submit!!');
                        return false;
                    }
                });
            },
            resetForm(formName) {
                this.$refs[formName].resetFields();
            }
        },
        mounted(){
            let _this = this;
            this.$axios.get("http://localhost:8181/findById/" + this.$route.query.id).then(function (response) {
                _this.ruleForm = response.data;
            });
        }
    }
</script>

<style scoped>
</style>

5、路由文件 router.js

import Vue from 'vue'

//1.导入路由依赖,安装 vue-router组件后系统带有的依赖
import VueRouter from 'vue-router'

//2.导入两个页面
import Login from "@/views/login";
import Second from "@/views/Second";
import Table from "@/views/table";
import AddBook from "@/views/addBook";
import Edit from "@/views/edit";

// 3.使用路由
Vue.use(VueRouter);

//4.创建路由对象,new VueRouter为上面import设置的名称
const router = new VueRouter({
    //没有history,访问URL会有#
    mode: "history",
    routes: [
        {
            path:"/login",
            component: Login
        },
        {
            path:"/second",
            component: Second
        },
        {
            path:"/table",
            component: Table
        },
        {
            path:"/addbook",
            component: AddBook
        },
        {
            path:"/edit",
            component: Edit
        },
    ]
});
export default router;

6、组件的全局配置 main.js

import Vue from 'vue'
import App from './App.vue'
import router from "./router/index"

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

import axios from "axios"
import qstring from "querystring"

// Vue 全局Vue对象,prototype原型设置全局属性
Vue.prototype.$axios = axios
Vue.prototype.$qstring=qstring

Vue.config.productionTip = false;
Vue.use(ElementUI);

new Vue({
    router,
    render: h => h(App),
}).$mount('#app')

总结

到此这篇关于Spring Boot和Vue前后端分离项目架构的文章就介绍到这了,更多相关Spring Boot Vue前后端分离内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Spring Boot和Vue前后端分离项目架构的全过程

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

flask和vue前后端分离项目部署的代码怎么写

本篇文章为大家展示了flask和vue前后端分离项目部署的代码怎么写,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。前段时间开发了一个项目, 我后端用的是flask框架写接口,前端用的是vue框架,项
2023-06-25

【SpringBoot+Vue】全网最简单但实用的前后端分离项目实战笔记 - 项目概述

配套视频地址:https://www.bilibili.com/video/BV1dG4y1T7yp/ 项目概述 1. 目标 通过学习本项目,深刻理解前后端分离的思想,具备独立搭建前后端分离项目的能力及功能扩展能力 2. 开发模式 3.
2023-08-16

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录