1小时学会SpringBoot3+Vue3前后端分离开发

首发于Enaium的个人博客


引言

大家可能刚学会JavaVue之后都会想下一步是什么?那么就先把SpringBootVue结合起来,做一个前后端分离的项目吧。

准备工作

首先你需要懂得JavaVue的基础知识,环境这里就不多说了,直接开始。

创建 SpringBoot 项目

使用IDEA旗舰版的可以直接使用自带Spring Initializr创建项目,其他的可以使用Spring Initializr创建项目。

语言选择Java,类型选择Gradle-KotlinJava选择 21,其他的都随便填。

20240423215241

20240423210415

接下来选择依赖,这里选择weblombok,数据库选择PostgreSQL,如果你使用的是MySQL就选它

20240423210635

20240423210727

之后点击创建自动打开项目,或者点击生成打开下载的项目

20240423210848
20240423210903

之后等待项目的依赖下载完成就好了

如果需要配置镜像那就在repositories中最上面添加腾讯云的镜像

repositories {maven {url = uri("https://mirrors.cloud.tencent.com/nexus/repository/maven-public")}mavenCentral()
}

首先我们需要创建数据库,比如一个图书管理系统,需要有一张图书表,有一些字段,比如标题、作者、创建时间、等等。

我们使用数据库管理工具来创建一个表吧。

20240423225934

注意这里使用的是Postgres,如果是MySQL类型略有不同。

之后我们就可以创建实体类了,这里需要先引入ORM框架依赖,这里我为了方便引入写了一个Gradle插件,把它写入到plugins中,接着在刷新一下项目就可以继续编写代码了。

plugins {// 省略其他插件...id("cn.enaium.jimmer.gradle") version "0.0.11"
}

我们创建一个接口Book添加一个EntityTable注解,之后添加一些方法,名称就是根据数据库中字段名称一样,只不过要把蛇形命名改为小驼峰。

@Entity
@Table(name = "book")
public interface Book {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)int id();String title();String author();LocalDateTime createTime();
}

写完之后,我们按下编译的快捷键(默认是 Ctrl+F9),之后就可以编写接口了。

@RestController
@RequiredArgsConstructor
public class BookController {private final JSqlClient sql;@GetMapping("/book")public List<Book> getBooks() {return sql.createQuery(Tables.BOOK_TABLE).select(Tables.BOOK_TABLE).execute();}@PostMapping("/book")public void saveBook(@RequestBody Book book) {sql.save(book);}
}

使用RequiredArgsConstructor注解可以为被final修饰的字段生成构造方法,这样就不用手动写构造方法了。

getBooks用于获取图书列表,首先使用createQuery创建一个查询,传入一张表,类似于from book,接着使用select选择所有字段,类似于select id, name, author, createTime,最后使用execute执行查询。
saveBook用于保存图书,使用save方法保存图书。

接下来需要配置允许跨域,这里使用CORS,在SpringBoot中配置CORS很简单,只需实现WebMvcConfigurer接口的addCorsMappings方法即可。

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedMethods("*").allowedOrigins("*").allowedHeaders("*");}
}

最后我们配置一下数据库链接。

spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres?currentSchema=sbv
spring.datasource.username=postgres
spring.datasource.password=postgres
jimmer.dialect=org.babyfish.jimmer.sql.dialect.PostgresDialect

如果是MySQL就把PostgresDialect改为MySqlDialect

这样我们的后端就写完了,接下来我们开始写前端。

创建 Vue 项目

这里使用pnpm create vue来创建,如果没有安装pnpm可以使用npm install -g pnpm来安装。

20240423215715

名称随便,之后使用TypescriptVue Router剩下的选否。

之后使用命令pnpm install安装依赖,并删除src下的所有文件。

编写App.vue

<script setup lang="ts"></script><template><h1>Vue 3 + Vite + TypeScript</h1>
</template>

编写main.ts

import { createApp } from "vue"; import App from "./App.vue"; const app = createApp(App); app.mount("#app");

这里我使用naive ui,使用命令安装pnpm add -D naive-ui,之后使用自动导入配置。

安装这两个插件pnpm add -D unplugin-auto-import unplugin-vue-components

之后修改vite.config.ts文件

import { fileURLToPath, URL } from "node:url"import { defineConfig } from "vite"
import vue from "@vitejs/plugin-vue"
import AutoImport from "unplugin-auto-import/vite"
import Components from "unplugin-vue-components/vite"
import { NaiveUiResolver } from "unplugin-vue-components/resolvers"// https://vitejs.dev/config/
export default defineConfig({plugins: [vue(),AutoImport({imports: ["vue",{"naive-ui": ["useDialog", "useMessage", "useNotification", "useLoadingBar"]}]}),Components({resolvers: [NaiveUiResolver()]})],resolve: {alias: {"@": fileURLToPath(new URL("./src", import.meta.url))}}
})

然后就可以继续编写页面了,首先在views中编写两个页面一个用来获取所有的图书,一个用来添加图书。

<script setup lang="ts">
import type { DataTableColumns } from "naive-ui"
import { ref } from "vue"interface Book {id: numbertitle: stringauthor: stringcreateTime: string
}const columns: DataTableColumns<Book> = [{title: "ID",key: "id"},{title: "Title",key: "title"},{title: "Author",key: "author"},{title: "Create Time",key: "createTime"}
]const books = ref<Book[]>([])fetch("http://localhost:8080/book").then((response) => response.json()).then((data: Book[]) => {books.value = data})
</script><template><n-data-table :columns="columns" :data="books" />
</template>
<script setup lang="ts">
import { ref } from "vue"
import { useMessage, type FormInst } from "naive-ui"interface BookInput {title?: stringauthor?: string
}const message = useMessage()const formRef = ref<FormInst | null>(null)
const bookInput = ref<BookInput>({})const save = () => {formRef.value?.validate().then((valid) => {if (valid) {fetch("http://localhost:8080/book", {method: "POST",headers: {"Content-Type": "application/json"},body: JSON.stringify(bookInput.value)}).then(() => {message.success("Book saved")})}})
}
</script><template><n-form ref="formRef" :model="bookInput"><n-form-item label="Title" path="title" :rule="[{ required: true, message: 'Please input title' }]"><n-input v-model:value="bookInput.title" /></n-form-item><n-form-item label="Author" path="author" :rule="[{ required: true, message: 'Please input author' }]"><n-input v-model:value="bookInput.author" /></n-form-item><n-button type="primary" @click="save">Save</n-button></n-form>
</template>

之后编写布局,在layouts下编写一个,BookLayout.vue,我们使用左侧一栏来选择页面,右侧来展示页面。

<script setup lang="ts"></script><template><n-layout has-sider><n-layout-sider content-style="padding: 24px;"><ul><li><RouterLink to="/book">Book</RouterLink></li><li><RouterLink to="/book/create">Create Book</RouterLink></li></ul></n-layout-sider><n-layout><n-layout-content content-style="padding: 24px;"><RouterView /></n-layout-content></n-layout></n-layout>
</template>

之后创建一个router目录,编写index.ts文件

import BookLayout from "@/layouts/BookLayout.vue"
import Books from "@/views/Books.vue"
import SaveBook from "@/views/SaveBook.vue"
import { createRouter, createWebHistory } from "vue-router"const router = createRouter({history: createWebHistory(),routes: [{path: "/book",component: BookLayout,children: [{path: "",component: Books},{path: "create",component: SaveBook}]}]
})export default router

之后在main.ts中引入router

import router from "./router"// 省略其他代码...app.use(router)

最后在App.vue中使用RouterView

<template><NMessageProvider><RouterView /></NMessageProvider>
</template>

这样我们的前端就写完了,接下来我们启动项目。

源码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/650276.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NAT网络地址转换实验(思科)

华为设备参考&#xff1a;NAT网络地址转换实验&#xff08;华为&#xff09; 一&#xff0c;技术简介 NAT&#xff08;Network Address Translation&#xff09;&#xff0c;即网络地址转换技术&#xff0c;是一种在现代计算机网络中广泛应用的技术&#xff0c;主要用于有效管…

c++中的指针

一、指针的基本概念 指针的作用&#xff1a;可以通过指针间接访问内存 内存编号是从0开始记录的&#xff0c;一般采用16进制数字表示。可以利用指针变量保存地址。 二、指针变量的定义和使用 指针变量定义语法&#xff1a; 数据类型 * 变量名 #include<iostream> u…

云原生架构(CloudNative)|文末送资料:马-云原生微服务治理大厂冲刺班56期

目录 文末福利&#xff1a;送资料 前言 一、部署架构发展史 二、三大技术基石 三、云原生的优点&#xff1a; 文末福利&#xff1a;送资料 云原生-马哥-云原生微服务治理大厂冲刺班56期[完结 第01节全新马哥Linux云计算高薪就业实战班VIP体验课 第02节ceph企业级存储实…

ACN 报告 2023:国家网络安全局的一年期报告

微信搜索关注&#xff1a;网络研究观 阅读获取更多信息。 公众号网络研究观 今天介绍国家网络安全局 (ACN) 编制的年度报告&#xff0c;该报告涉及 2023 年开展的活动&#xff0c;我们将完整发布该报告。 这份121页的报告分为七个部分&#xff0c;说明该机构如何通过以预防、管…

一种利用合法工具渗透的新型方法

摘要 黑客在执行各种攻击步骤时倾向于优先选择合法工具&#xff0c;因为这些工具能帮助他们规避检测系统&#xff0c;同时将恶意软件开发成本降至最低。网络扫描、捕获进程内存转储、数据外泄、远程运行文件&#xff0c;甚至加密驱动器——所有这些都可以通过可信软件完成。为了…

基于socket编程实现TCP和UDP的通信流程

socket编程的常用函数&#xff0c;可以参考以下这篇博客 socket编程-----常用socket编程函数https://blog.csdn.net/ZZZCY2003/article/details/138071210 关于TCP的三次挥手、四次挥手过程和UDP的报文分析可以参考以下两篇博客 计算机网络--运输层https://blog.csdn.net/ZZ…

SimCal(ECCV2020)

文章目录 AbstractMethodUsing Existing Long-tail Classification ApproachesLoss Re-weightingFocal Loss略 Proposed SimCal:Calibrating the ClassifierDual Head Inference Experiment创新 原文 代码 Abstract 本文主要研究了长尾分布下的实例分割问题&#xff0c;并提出…

区块链技术与应用学习笔记(8-9节)——北大肖臻课程

目录 8.挖矿 对于全节点和轻节点思考问题&#xff1f; ①全节点在比特币的主要作用&#xff1f; ②挖矿时当监听到别人已经挖出区块并且延申了最长合法链此时应该立刻放弃当前区块在 本地重新组装一个指向最后这个新合法区块的候选区块&#xff0c;重新开始挖矿。节点这么做…

数字藏品平台搭建重点,会用到哪些三方服务?

数字藏品平台的搭建是一个复杂且多面的过程&#xff0c;它涉及到技术实现、内容管理、用户体验、安全保障等多个方面。以下是一些关键的搭建重点以及可能用到的第三方服务&#xff1a; 技术架构与稳定性&#xff1a; 选择稳定、可扩展的技术框架&#xff0c;确保平台能够应对大…

【Arduino板接口及应用】外部中断接口及应用:中断的概念,中断服务程序,中断优先级,中断嵌套,Arduino的外部中断引脚

“等待也是种信念,海的爱太深,时间太浅。 ”——《老人与海》 🎯作者主页: 追光者♂🔥 🌸个人简介: 📝[1] CSDN 博客专家📝 🏆[2] 人工智能领域优质创作者🏆 🌟[3] 2022年度博客之星人工智能领域TOP4🌟 🌿[4] 2023年城市之星领跑者T…

VTK----VTK数据结构详解2(计算机篇)

在VTK中&#xff0c;属性数据和点都用数据数组&#xff08;data arrays&#xff09;表示。某些属性数据&#xff08;例如法线、张量&#xff09;需要具有与其定义一致的元组&#xff08;在计算机编程中&#xff0c;元组&#xff08;tuple&#xff09;用来表示存储多种数据类型的…

一文解析golang中的协程与GMP模型

文章目录 前言1、线程实现模型1.1、用户级线程与内核级线程1.2、内核级线程模型1.3、用户级线程模型1.3、两级线程模型 2、GMP模型2.1、GMP模型概述2.1、GMP v1版本 - GM模型2.2、GMP v2版本 - GMP模型2.3、GMP相关源码2.4 调度流程2.5 设计思想 3.总结 前言 并发(并行&#x…