hello我是索奇,本套项目对应bilibili视频,大家可以结合视频看哈,有些基础的只看笔记也可,这篇笔记做了很久,也拓展了很多东西,对小白和积累经验的伙伴们都有帮助~
有用的话可以关注点赞收藏一波哈~
项目概述
1. 目标
通过学习本项目,深刻理解前后端分离的思想,具备独立搭建前后端分离项目的能力及功能扩展能力
2. 开发模式
3. 技术栈
前端技术 说明
Vue 前端框架
Vuex 全局状态管理框架
ElementUI 前端UI框架
Axios 前端HTTP框架
vue-element-admin 项目脚手架
后端技术 说明
SpringBoot 容器+MVC框架
MyBatis ORM框架
MyBatis-plus MyBatis增强工具
Redis 非关系型数据库
Redis是处理缓存的非关系型数据库,在这里先有个印象
数据库
数据库xdb
1. 用户表
tips
在第一章节仅需用户表即可满足开发需要,但为了后期繁琐,重新回来创建表,建议还是创建吧
CREATE TABLE `x_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(50) NOT NULL, `password` varchar(100) DEFAULT NULL, `email` varchar(50) DEFAULT NULL, `phone` varchar(20) DEFAULT NULL, `status` int(1) DEFAULT NULL, `avatar` varchar(200) DEFAULT NULL, `deleted` INT(1) DEFAULT 0, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; insert into `x_user` (`id`, `username`, `password`, `email`, `phone`, `status`, `avatar`, `deleted`) values('1','admin','123456','super@aliyun.com','18677778888','1','https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif','0'); insert into `x_user` (`id`, `username`, `password`, `email`, `phone`, `status`, `avatar`, `deleted`) values('2','zhangsan','123456','zhangsan@gmail.com','13966667777','1','https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif','0'); insert into `x_user` (`id`, `username`, `password`, `email`, `phone`, `status`, `avatar`, `deleted`) values('3','lisi','123456','lisi@gmail.com','13966667778','1','https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif','0'); insert into `x_user` (`id`, `username`, `password`, `email`, `phone`, `status`, `avatar`, `deleted`) values('4','wangwu','123456','wangwu@gmail.com','13966667772','1','https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif','0'); insert into `x_user` (`id`, `username`, `password`, `email`, `phone`, `status`, `avatar`, `deleted`) values('5','zhaoer','123456','zhaoer@gmail.com','13966667776','1','https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif','0'); insert into `x_user` (`id`, `username`, `password`, `email`, `phone`, `status`, `avatar`, `deleted`) values('6','songliu','123456','songliu@gmail.com','13966667771','1','https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif','0');
2. 角色表
CREATE TABLE `x_role` ( `role_id` int(11) NOT NULL AUTO_INCREMENT, `role_name` varchar(50) DEFAULT NULL, `role_desc` varchar(100) DEFAULT NULL, PRIMARY KEY (`role_id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4; insert into `x_role` (`role_id`, `role_name`, `role_desc`) values('1','admin','超级管理员'); insert into `x_role` (`role_id`, `role_name`, `role_desc`) values('2','hr','人事专员'); insert into `x_role` (`role_id`, `role_name`, `role_desc`) values('3','normal','普通员工');
3. 菜单表
CREATE TABLE `x_menu` ( `menu_id` int(11) NOT NULL AUTO_INCREMENT, `component` varchar(100) DEFAULT NULL, `path` varchar(100) DEFAULT NULL, `redirect` varchar(100) DEFAULT NULL, `name` varchar(100) DEFAULT NULL, `title` varchar(100) DEFAULT NULL, `icon` varchar(100) DEFAULT NULL, `parent_id` int(11) DEFAULT NULL, `is_leaf` varchar(1) DEFAULT NULL, `hidden` tinyint(1) DEFAULT NULL, PRIMARY KEY (`menu_id`) ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4; insert into `x_menu`(`menu_id`,`component`,`path`,`redirect`,`name`,`title`,`icon`,`parent_id`,`is_leaf`,`hidden`) values (1,'Layout','/user','/user/list','userManage','用户管理','userManage',0,'N',0),(2,'user/user','list',NULL,'userList','用户列表','userList',1,'Y',0),(3,'user/role','role',NULL,'roleList','角色列表','role',1,'Y',0),(4,'user/permission','permission',NULL,'permissionList','权限列表','permission',1,'Y',0);
4. 用户角色映射表
CREATE TABLE `x_user_role` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) DEFAULT NULL, `role_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4; insert into `x_user_role` (`id`, `user_id`, `role_id`) values('1','1','1');
5. 角色菜单映射表
CREATE TABLE `x_role_menu` ( `id` int(11) NOT NULL AUTO_INCREMENT, `role_id` int(11) DEFAULT NULL, `menu_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;
前端笔记
1. node环境
官网:Node.js
注意,node可以比这个稍低,但不要更高
2. 下载vue-admin-template
下载 & 指南
https://panjiachen.gitee.io/vue-element-admin-site/zh/guide/
3. 项目初始化
1.解压至非中文无空格目录下(防止出现异常)
2.vscode、idea等工具打开项目
我这里用的是idea
拓展
控制台输入 ctrl + c 终止服务
这里需要用到node.js
不想要被配置bug弄头疼的看这里!
安装的时候选择node.js版本16.12以下版本,防止后期各种错误,麻烦的更改配置(脚手架不支持新版本)
自己新建一个目录,别把nodejs的文件混杂了
安装完之后的目录是这样的
设置淘宝镜像,加速
注意:npm install命令必须在package.json文件所在的同级目录下执行。这是因为npm install命令会根据package.json文件中的依赖信息来安装相应的包。如果package.json文件不在当前目录下,npm将无法找到它并执行安装。
首次设置镜像,便于加速
npm config set registry http://registry.npm.taobao.org/
npm install
1.运行测试
部署看一下有没有问题
npm run dev
默认打开登录页面,登录之后成功进入主页面
2.配置修改
语法校验:lintOnSave
表示当前为开发环境,此时ESLint将会在保存文件时进行代码检查。不开启的话可以改为false
默认打开浏览器:true
title:自己改喜欢的名字~
mock:用于模拟后端数据(后端建立之后可以删除了)
以下是视频中配置的内容,我这里除了名字,其它都保持一致,方便和视频效果一样
idea中点击Navigator可以在这里找到相应的文件更改名字
快捷键ctrl+shift+n
"symbol"(符号)指的是代码中的标识符,例如类名、方法名、变量名等。当您使用搜索功能时,可以选择搜索符号,从而查找与特定标识符相关的代码。我们可以选择symbols定位title等内容
快捷键ctrl+shift+alt+n
都改好之后重启服务测试
4. 登录页修改
都改好之后重启服务测试
4. 登录页修改
1.中文描述
2.背景图
3.中文描述
4.背景图
5.所有的英文我们都可以根据英文查找进行选择性修改
图片放在assets里面,然后修改.login-container(完整项目已经打包放进去了,)
background-image: url('../../assets/bg.jpeg'); 1
登录框调整
1.登录用户名取消限制
5. 修改右上角用户下拉菜单
src/layout/components/Navbar.vue
索奇感觉自带的这几个下拉菜单还不错,这里没有做任何修改
//下拉菜单
<el-dropdown-item>
6. 首页面包屑导航
7. 菜单初始化
1.在src\views目录下创建sys模块目录、test模块目录(充数用,后续可用作权限分配测试)
2.在sys下创建user.vue、role.vue两个组件文件
在test下创建test1.vue、test2.vue、test3.vue
3.修改路由配置
{ path: '/sys', component: Layout, redirect: '/sys/user', name: 'sys', meta: { title: '系统管理', icon: 'sys' }, children: [ { path: 'user', name: 'user', component: () => import('@/views/sys/user'), meta: { title: '用户管理', icon: 'userManage' } }, { path: 'role', name: 'role', component: () => import('@/views/sys/role'), meta: { title: '角色管理', icon: 'roleManage' } } ] }, { path: '/test', component: Layout, redirect: '/test/test1', name: 'test', meta: { title: '功能测试', icon: 'form' }, children: [ { path: 'test1', name: 'test1', component: () => import('@/views/test/test1'), meta: { title: '测试点一', icon: 'form' } }, { path: 'test2', name: 'test2', component: () => import('@/views/test/test2'), meta: { title: '测试点二', icon: 'form' } }, { path: 'test3', name: 'test3', component: () => import('@/views/test/test3'), meta: { title: '测试点三', icon: 'form' } } ] }
图标svg文件可上 iconfont-阿里巴巴矢量图标库 下载
8. 标签栏导航
1.@/layout/components/AppMain.vue
<keep-alive :include="cachedViews"> <router-view :key="key" /> </keep-alive> cachedViews() { return this.$store.state.tagsView.cachedViews }
2.复制vue-element-admin项目中的文件到相应的目录中
1.idea直接复制粘贴即可(VsCode打开文件夹粘贴)
@/layout/components/TagsView @/store/modules/tagsView.js @/store/modules/permission.js
3.修改文件@store/getters.js
visitedViews: state => state.tagsView.visitedViews, cachedViews: state => state.tagsView.cachedViews, permission_routes: state => state.permission.routes
4.修改文件@store/index.js
import Vue from 'vue' import Vuex from 'vuex' import getters from './getters' import app from './modules/app' import settings from './modules/settings' import user from './modules/user' import tagsView from './modules/tagsView' Vue.use(Vuex) const store = new Vuex.Store({ modules: { app, settings, user, tagsView }, getters }) export default store
5.修改文件@\layout\index.vue
1.导入、注册
6.修改文件@layout\components\index.js
在index.js下面导出组件,其他模块可以通过导入(import)TagsView组件来使用它。
export { default as TagsView } from './TagsView'
7.Affix 固钉 当在声明路由是 添加了 Affix 属性,则当前tag会被固定在 tags-view中(不可被删除)
报错处理
deep报错将其改为 :: v-deep ::v-deep { .el-scrollbar__bar { bottom: 0px; } .el-scrollbar__wrap { height: 49px; } }
9. 登录接口梳理
准备对接后端
在调试页面的 Network 标签中,可以查看浏览器发送和接收的所有网络请求。每个请求都是一个条目
下面的url可以更改(保证名字有意义)
接口 url method
登录 /user/login post
获取用户信息 /user/info get
注销 /user/logout post
code:HTTP 状态码,表示请求的返回码。20000 表示成功,其他代码表示不同类型的错误。(可以改前端成功对应的码)
data:是请求返回的数据。
在预览中可以查看这些数据
{ "code": 20000, "data": { "token": "admin-token" } } { "code": 20000, "data": { "roles": ["admin"], "introduction": "I am a super administrator", "avatar": "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif", "name": "Super Admin" } } { "code": 20000, "data": "success" }
拓展
json.cn转换为json格式,易于观察
JSON在线解析及格式化验证 - JSON.cn
在线JSON校验格式化工具(Be JSON)
10. 对接后端接口
1.修改 .env.development 中的base api,打包部署的话要修改.env.production
VUE_APP_BASE_API = 'http://localhost:9999'
2.修改vue.config.js,屏蔽mock请求
3.修改src\api\user.js,将url中的/vue-admin-template去掉
4.测试,预期会出现跨域错误
5.后端做跨域处理测试应该成功,并可在调试窗口观察接口调用情况
11. 用户管理
预览
用户查询
1.定义userManager.js
2.分页序号处理
<template slot-scope="scope"> {{(searchModel.pageNo-1) * searchModel.pageSize + scope.$index + 1}} </template> 123
用户新增
1.窗口关闭后数据还在
监听close,清理表单
2.表单数据验证
常规验证
自定义验证
3.窗口关闭后上次验证结果还在
用户修改
用户删除
后端
1. 项目初始化
1.创建springboot项目:2.7.8
2.pom依赖
<!-- web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- mysql --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> </dependency> <!-- mybatis-plus --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.2</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.5.2</version> </dependency> <!-- freemarker --> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> </dependency> <!-- lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
拓展依赖
mybatis-plus-generator:这个依赖项是 MyBatis-Plus 的代码生成器模块。使用这个模块,你可以根据数据库表自动生成 MyBatis-Plus 的实体类、Mapper 接口和 XML 映射文件。这个模块可以大大简化开发人员的工作,减少手动编写重复代码的工作量。
freeMarker:FreeMarker 是一个功能强大的模板引擎,它可以帮助我们将数据模型和模板文件结合起来,生成各种文本输出,例如 HTML 页面、电子邮件、配置文件等等。以下是 FreeMarker 的主要用途:
1.Web 应用程序视图渲染:FreeMarker 可以作为 Web 应用程序中的模板引擎,帮助我们将数据模型和模板文件结合起来,生成 HTML 页面。
2.邮件模板:FreeMarker 可以帮助我们生成电子邮件的内容,例如邮件正文、邮件标题等等。
3.报表生成:FreeMarker 可以帮助我们生成各种类型的报表,例如 PDF、Excel、Word 等等。
4.代码生成:FreeMarker 可以帮助我们根据模板生成代码文件,例如 Java 类、XML 文件等等。
5.配置文件生成:FreeMarker 可以帮助我们生成各种类型的配置文件,例如 XML 配置文件、属性文件等等。
3.yml
1.把配置文件改为yml格式,并更改使用下面代码
server: port: 9999 spring: datasource: username: root password: 123456 url: jdbc:mysql:///xdb redis: port: 6379 host: localhost logging: level: # 想要输出那个目录下面的debug日志,就配置哪一个,我设置的groupid是suoqi,这里和视频不一样,自己别出错了~ com.suoqi: debug
拓展
jdbc:mysql:///database 表示连接到本地默认端口(3306)的 MySQL 数据库中的 database 数据库。这种方式相当于使用主机名为 localhost 或 127.0.0.1 的地址连接 MySQL 数据库。
如果要连接到其他主机上的 MySQL 数据库,可以将主机名和端口号添加到 URL 中,例如:
jdbc:mysql://hostname:port/database
其中,hostname 是要连接的 MySQL 服务器的主机名或 IP 地址,port 是 MySQL 服务器的端口号,默认是 3306。
测试
连接池使用默认的即可,不需要设置 spring.datasource.type。如果你使用的是较早的版本,需要手动设置。
默认 HikariCP 在性能和稳定性方面都表现非常出色,是目前最快的连接池之一。但是,并不是说 HikariCP 在所有情况下都是最快的,因为连接池的性能还受到许多其他因素的影响,例如数据库类型、数据库驱动程序、JVM 版本、操作系统等等。
spring: datasource: url: jdbc:mysql:///xdb username: root password: 123456 type: com.zaxxer.hikari.HikariDataSource # hikari: # maximum-pool-size: 20 # connection-timeout: 5000 这些是可选值,不配置使用默认的也行,为了让大家了解还有很多参数可以配置
拓展
driver-class-name 是 JDBC 驱动程序的完整类名,它用于告诉应用程序使用哪个 JDBC 驱动程序与数据库建立连接。在 Spring Boot 的数据源配置中,如果使用的是 Spring Boot 默认支持的数据库,如 MySQL、PostgreSQL 等,就不需要再显式配置 driver-class-name,因为 Spring Boot 会自动根据 JDBC URL 推断出驱动程序的类名。例如,如果 JDBC URL 是 jdbc:mysql://localhost:3306/mydb,那么 Spring Boot 就会自动使用 MySQL 驱动程序(即 com.mysql.jdbc.Driver)。但是,如果使用的是其他数据库,或者 JDBC URL 中没有包含数据库类型信息,那么就需要手动配置 driver-class-name。
配置的话,如下格式, Oracle 数据库,可以这样配置数据源:
spring: datasource: url: jdbc:oracle:thin:@localhost:1521:mydb username: myuser password: mypassword driver-class-name: oracle.jdbc.driver.OracleDriver
在这个配置中,driver-class-name 显式指定了 Oracle JDBC 驱动程序的类名。
2. Mybatis-plus代码生成
官网
MyBatis-Plus
生成器代码(MybatisPlus官网最新代码和项目中不适配,如果报错可以删除新版本的代码,模板如下)
public class CodeGenerator { public static void main(String[] args) { String url = "jdbc:mysql:///xdb"; String username = "root"; String password = "123456"; String author = "suoqi"; // 定义的是src下面的java目录的绝对路径 String outPath = "F:\\projects\\java\\Springboot+Vue管理系统01\\backend-admin-template-4.4.0\\src\\main\\java"; String parentPackage = "com.suoqi"; String moduleName = "sys"; // // 复制类路径resources的绝对路径 后面加上mapper+模块名字 String mapperLocation = "F:\\projects\\java\\Springboot+Vue管理系统01\\backend-admin-template-4.4.0\\src\\main\\resources\\mapper\\sys"; FastAutoGenerator.create("url", "username", "password") .globalConfig(builder -> { builder.author(author) // 设置作者 //.enableSwagger() // 开启 swagger 模式 (这里我们不需要生成Swagger相关的代码) //.fileOverride() // 覆盖已生成文件 .outputDir(outPath); // 指定输出目录 }) .packageConfig(builder -> { builder.parent(parentPackage) // 设置父包名 .moduleName(moduleName) // 设置父包模块名 .pathInfo(Collections.singletonMap(OutputFile.xml, mapperLocation)); // 设置mapperXml生成路径 }) .strategyConfig(builder -> { builder.addInclude("t_simple") // 设置需要生成的表名 .addTablePrefix("t_", "c_"); // 设置过滤表前缀 }) .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板 .execute(); } }
注意
mybatis-plus: # mapper-locations: classpath*:mapper/*.xml # global-config: # db-config: # id-type: auto # field-strategy: not_empty # table-prefix: mp_ # logic-delete-value: 1 # logic-not-delete-value: 0 # logic-delete-field: is_deleted
mapper目录需要和配置一致才能够生效
使用快速代码生成器-在Test下面创建一个类CodeGenerator
1. package com.suoqi;
import com.baomidou.mybatisplus.generator.FastAutoGenerator; import com.baomidou.mybatisplus.generator.config.OutputFile; import com.baomidou.mybatisplus.generator.config.rules.DbColumnType; import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine; import java.sql.Types; import java.util.Collections; /** * @author 即兴小索奇 * @version 1.0 * @date 2023/6/25 1:05 * @description */ public class CodeGenerator { public static void main(String[] args) { String url = "jdbc:mysql:///xdb"; String username = "root"; String password = "123456"; String author = "suoqi"; // 定义的是src下面的java目录的绝对路径 String outPath = "F:\\projects\\java\\Springboot+Vue管理系统01\\backend-admin-template-4.4.0\\src\\main\\java"; String parentPackage = "com.suoqi"; String moduleName = "sys"; // // 复制类路径resources的绝对路径 String mapperLocation = "F:\\projects\\java\\Springboot+Vue管理系统01\\backend-admin-template-4.4.0\\src\\main\\resources\\mapper\\sys"; // 带,分割代表多个表 String tables = "x_user,x_role,x_menu,x_user_role,x_role_menu"; FastAutoGenerator.create(url, username, password) .globalConfig(builder -> { builder.author(author) // 设置作者 //.enableSwagger() // 开启 swagger 模式 (这里我们不需要生成Swagger相关的代码) //.fileOverride() // 覆盖已生成文件 .outputDir(outPath); // 指定输出目录 }) .packageConfig(builder -> { builder.parent(parentPackage) // 设置父包名 .moduleName(moduleName) // 设置父包模块名 .pathInfo(Collections.singletonMap(OutputFile.xml, mapperLocation)); // 设置mapperXml生成路径 }) .strategyConfig(builder -> { builder.addInclude(tables) // 设置需要生成的表名 // 设置过滤表前缀 ,比如设置了过滤x_即 x_user = user .addTablePrefix("x_"); // 设置过滤表前缀 }) .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板 .execute(); } }
运行即可生成相应的文件
2.启动类加注解
//表示扫描com.suoqi包及其子包下所有以Mapper结尾的接口,并将其注册到MyBatis中
@MapperScan("com.suoqi.*.mapper")
3.测试
启动类
/** * RestController=Controller+ResponseBody * 这里的/user/all 是自定义的 */ @RestController @RequestMapping("/user") public class UserController { @Autowired private IUserService userService; @GetMapping("/all") public List<User> getAllUser() { List<User> list = userService.list(); return list; } }
拓展
@Resources 注解
@Resource(基于类的名称)注解与@Autowired注解类似,也是用来进行依赖注入的,@Resource是Java层面所提供的注解(不依赖Spring框架)
它有一个name属性,@Resource如果name属性有值,那么Spring会直接根据所指定的name值去Spring容器找Bean对象,如果找到了则成功,如果没有找到则报错。
查找顺序如下:
按照名称查找:如果指定了 name 属性,则按照该名称查找 Bean。
按照类型查找:如果没有指定 name 属性,则按照属性类型查找 Bean。如果找到多个同类型的 Bean,则会抛出异常。
@Autowired(基于类型type)是Spring所提供的注解,它们依赖注入的底层实现逻辑也不同。
按照类型byType的方式查找:如果属性的类型在 Spring 容器中只有一个 Bean,则自动装配该 Bean。
按照名称查找:如果属性的类型在 Spring 容器中有多个 Bean,则按照属性名称与 Bean 的名称进行匹配。如果匹配到了一个同名的 Bean,则自动装配该 Bean;否则抛出异常。
@Resource 注解是 Java EE 规范中定义的注解,不依赖于 Spring 框架,因此可以在任何 Java EE 应用程序中使用。但是,在 Spring 应用程序中,建议使用 @Autowired 或 @Inject 注解来进行 Bean 的自动装配。
3. 公共响应类
保证每一个接口返回的格式与前端格式保持一致,需要创建格式统一的类并附带三个参数:
code
message(描述)
data(类型不确定)
src/main/java/com/common/vo/Result.java
定义成功和失败的方法
@Data @NoArgsConstructor @AllArgsConstructor public class Result<T> { private Integer code; private String message; private T data; public static<T> Result<T> success(){ return new Result<>(20000,"success",null); } public static<T> Result<T> success(T data){ return new Result<>(20000,"success",data); } public static<T> Result<T> success(T data, String message){ return new Result<>(20000,message,data); } public static<T> Result<T> success(String message){ return new Result<>(20000,message,null); } public static<T> Result<T> fail(){ return new Result<>(20001,"fail",null); } public static<T> Result<T> fail(Integer code){ return new Result<>(code,"fail",null); } public static<T> Result<T> fail(Integer code, String message){ return new Result<>(code,message,null); } public static<T> Result<T> fail( String message){ return new Result<>(20001,message,null); } }
拓展session、token、Cookie
拓展
什么是单体项目?
单体项目是指整个应用程序都部署在一个单独的进程中,所有的功能和模块都在同一个代码库中。
什么是微服务架构?
微服务架构是一种将一个大型应用程序拆分成多个小型的服务,每个服务都独立运行在自己的进程中,服务之间通过网络进行通信。每个服务都有自己的代码库和数据库,可以独立部署和扩展。微服务架构可以提高系统的可伸缩性和可维护性,但也会增加系统的复杂性和运维成本。
什么是前后端分离架构?
前后端分离是一种架构模式,它将应用程序的前端和后端分开开发、部署和维护。在前后端分离架构中,前端主要负责展示和交互逻辑,后端主要负责数据处理和业务逻辑。前端和后端之间通过API进行通信,前端通过API调用后端提供的服务获取数据,后端通过API接收前端传递的请求并返回处理结果。
前后端分离session还有用吗
前后端完全分离后,由于前端不再接受后端传来的渲染好的HTML页面,而是后端只提供RESTful API接口,前端通过AJAX请求后台返回的
JSON数据自己进行渲染,所以后台不再需要用session来保存状态,前端使用session效果不好甚至有风险,采用令牌(token)的方式来代替session。使用令牌的优势在于前后端各自按照约定来生成、验证、传递、存储令牌,实现了无状态无session的前后端分离。
在Vue前后端分离架构中,同样采用令牌(token)的方式来代替session。在Vue应用中,可以将令牌存储在Vuex或者localstorage中,在每次请求API时携带对应的令牌来获取响应数据。