当前位置: 首页 > news >正文

经营网站 备案seo网站优化插件

经营网站 备案,seo网站优化插件,软件下载中心,人社部回应:一建一造停文章目录 1. 后端项目搭建 1.1 环境准备1.2 数据表准备1.3 SpringBoot3项目创建1.4 MySql环境整合#xff0c;使用druid连接池1.5 整合mybatis-plus 1.5.1 引入mybatis-plus1.5.2 配置代码生成器1.5.3 配置分页插件 1.6 整合swagger3#xff08;knife4j#xff09; 1.6.1 整…文章目录 1. 后端项目搭建 1.1 环境准备1.2 数据表准备1.3 SpringBoot3项目创建1.4 MySql环境整合使用druid连接池1.5 整合mybatis-plus 1.5.1 引入mybatis-plus1.5.2 配置代码生成器1.5.3 配置分页插件 1.6 整合swagger3knife4j 1.6.1 整合1.6.2 使用 1.7 数据交互处理 1.7.1 响应数据封装公共返回数据类1.7.2 分页查询返回数据封装 1.8 全局异常处理1.9 整合JWT生成token1.10 封装ThreadLocal 工具类1.11 MD5封装1.12登录验证拦截1.13 登录和获取当前用户信息接口处理 2. 前端项目搭建 2.1 环境准备2.2 创建Vue3项目2.3 项目搭建准备2.4 Element Plus 安装使用2.5 axios 安装使用 2.5.1 安装2.5.2 配置创建实例配置请求、响应拦截器2.5.3 配置跨域 2.6 Vue Router 安装使用2.7 Pinia状态管理库2.7.1 Pinia持久化插件-persist2.8 搭建管理页面基础框架 2.8.1 在src下创建api目录次目录存放请求http方法的封装创建user.js 里边写封装请求方法2.8.2 登录页面2.8.3 布局页面 3.项目代码 项目使用SpringBoot3Vue3 后端使用springboot3, mybatisPlus, druid,knife4j(swagger3),Jwt; 前端 vue3 , element-plus, axios, pinia, vue-router; 项目前后端分离 可持续扩展 代码放到最后 1. 后端项目搭建 1.1 环境准备 - spring-boot3 最低支持jdk17, 所以需要准备jdk17环境 - Idea 版本IntelliJ IDEA 2021.2及以后版本关系参考[https://blog.csdn.net/m0_62258564/article/details/134527268](https://blog.csdn.net/m0_62258564/article/details/134527268) - maven 版本参考以上链接 - MySql81.2 数据表准备 创建数据库 base_manage 并创建表 CREATE TABLE user(id INT NOT NULL AUTO_INCREMENT COMMENT 主键,login_name VARCHAR(255) NOT NULL COMMENT 登录名账号,password VARCHAR(255) NOT NULL COMMENT 密码,name varchar(50) NOT NULL COMMENT 姓名,sex char(1) NOT NULL COMMENT 性别,phone VARCHAR(20) COMMENT 联系电话,PRIMARY KEY(id))COMMENT 用户信息表;用户表只是便于后续过程搭建操作可根据需求修改 1.3 SpringBoot3项目创建 springboot版本可根据需求选择这里选则默认的3.2.4 耐心等待项目构建完成 构建完成pom文件如下请注意mysql驱动包groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId较之前版本有所改变 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion3.2.4/versionrelativePath/ !-- lookup parent from repository --/parentgroupIdcom.buzhisuoyun/groupIdartifactIdbase_manage/artifactIdversion0.0.1-SNAPSHOT/versionnamebase_manage/namedescriptionbase_manage/descriptionpropertiesjava.version17/java.version/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdcom.mysql/groupIdartifactIdmysql-connector-j/artifactIdscoperuntime/scope/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency/dependenciesbuildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/plugin/plugins/build/project1.4 MySql环境整合使用druid连接池 添加 jdbc依赖防止项目启动时找不到Bean报错 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-jdbc/artifactId /dependency添加druid依赖 !-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-3-starter -- dependencygroupIdcom.alibaba/groupIdartifactIddruid-spring-boot-3-starter/artifactIdversion1.2.20/version /dependency项目使用yml格式配置文件修改resources下application.properties 为application.yml, 并删除文件内容 配置项目端口号 server:port: 8099配置数据源和druid 连接池 spring:# 数据源datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/base_manage?serverTimezoneUTCusername: rootpassword: root启动项目 查看日志端口和druid 初始化 整合成功 1.5 整合mybatis-plus 1.5.1 引入mybatis-plus 官网地址 https://baomidou.com/ 1、添加依赖 !-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-spring-boot3-starter -- dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-spring-boot3-starter/artifactIdversion3.5.5/version /dependency2、配置 # mybatis-plus mybatis-plus:configuration:# sql日志, 开发调试时开启log-impl: org.apache.ibatis.logging.stdout.StdOutImplglobal-config:db-config:id-type: auto启动项目出现mybatis-plus日志 1.5.2 配置代码生成器 1.引入相关依赖 !-- mybatis-plus 代码生成器-- dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-generator/artifactIdversion3.5.5/version /dependency!-- mybatis-plus代码生成器模板引擎 -- dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-freemarker/artifactId/dependency新建utis包并在下边创建MybatisPlusGenerator.java代码生成器配置类 package com.buzhisuoyun.base_manage.utils; 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.io.File; import java.sql.Types; import java.util.Collections; public class MybatisPlusGenerator { static final String url “jdbc:mysql://127.0.0.1:3306/base_manage?serverTimezoneUTC”; // 数据库地址 static final String username “root”; // 数据库用户名 static final String password “root”; // 数据库密码 static final String authorName “buzhisuoyun”; // 作者名 static final String parentPackageNameResource “com/buzhisuoyun/base_manage”; // mapper.xml路径 static final String parentPackageNameJava “com.buzhisuoyun.base_manage”; // java 文件父包名 // 要生成代码对应的数据表名 static final String tableName “user”; public static void main(String[] args) {FastAutoGenerator.create(url, username, password)// 1.全局配置.globalConfig(builder - {builder.author(authorName) // 设置作者.enableSpringdoc() // 开启 swagger 模式// 获取当前工程路径并定位到项目java目录下.outputDir(System.getProperty(user.dir) /src/main/java); // 指定输出目录})// 2.数据源配置.dataSourceConfig(builder - builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) - {int typeCode metaInfo.getJdbcType().TYPE_CODE;if (typeCode Types.SMALLINT) {// 自定义类型转换return DbColumnType.INTEGER;}return typeRegistry.getColumnType(metaInfo);}))// 3.包名策略配置.packageConfig(builder - {builder.parent(parentPackageNameJava) // 设置父包名.entity(entity).mapper(mapper).service(service).serviceImpl(service.impl).controller(controller)//.moduleName(system) // 设置父包模块名.pathInfo(Collections.singletonMap(OutputFile.xml, System.getProperty(user.dir) /src/main/resources/ parentPackageNameResource /mapper)); // 设置mapperXml生成路径})// 策略配置.strategyConfig(builder - {builder.addInclude(tableName) // 设置需要生成的表名// 覆盖已生成文件.entityBuilder().enableFileOverride().mapperBuilder().enableFileOverride().serviceBuilder().enableFileOverride().formatServiceFileName(%sService);//.addTablePrefix(t_, c_); // 设置过滤表前缀})// 配置模板.templateConfig(builder - {//builder.controller(); // 不生成controller}).templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板默认的是Velocity引擎模板.execute(); }} 修改数据库相关信息修改authorName修改parentPackageNameResource parentPackageNameJava修改tableName 要生成代码的数据表名称多个表使用分割.enableSpringdoc() 可以选择生成swagger3文档注释 修改完成后运行main函数生成相应代码mapper.xml在resource下与java同路径下 实体类import io.swagger.v3.oas.annotations.media.Schema;报错是因为swagger3依赖还未导入下边整合swagger3后就不会报错了 1.5.3 配置分页插件 新建config包并在下边创建配置类MybatisPlusConfig.java package com.buzhisuoyun.base_manage.config;import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;Configuration MapperScan(com/buzhisuoyun/base_manage/mapper) public class MybatisPlusConfig {/*** 添加分页插件*/Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//如果配置多个插件,切记分页最后添加//interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); 如果有多数据源可以不配具体类型 否则都建议配上具体的DbTypereturn interceptor;} }MapperScan(“com/buzhisuoyun/base_manage/mapper”) 扫描mapper路劲也可在启动类配置 1.6 整合swagger3knife4j 1.6.1 整合 引入依赖 !-- API 文档 knife4j -- !-- https://mvnrepository.com/artifact/com.github.xiaoymin/knife4j-openapi3-jakarta-spring-boot-starter -- dependencygroupIdcom.github.xiaoymin/groupIdartifactIdknife4j-openapi3-jakarta-spring-boot-starter/artifactIdversion4.5.0/version /dependency配置 # springdoc-openapi 配置 springdoc:swagger-ui:path: /swagger-ui.htmltags-sorter: alphaoperations-sorter: alphaapi-docs:path: /v3/api-docsgroup-configs:- group: defaultpaths-to-match: /**packages-to-scan: com.buzhisuoyun.base_manage# knife4j 配置 knife4j:# 是否启用增强enable: true# 开启生产环境屏蔽production: false# 是否认证登录basic:# basic是否开启默认为falseenable: trueusername: knife4jpassword: knife4jsetting:language: zh_cnenable-version: trueenable-swagger-models: true在config下创建配置类 package com.buzhisuoyun.base_manage.config;import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Info; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;Configuration public class Knife4jConfig {Beanpublic OpenAPI springShopOpenApi() {return new OpenAPI()// 接口文档标题.info(new Info().title(接口文档).description(api接口文档).version(1.0版本));} }配置完后启动项目访问路径http://localhost:9999/doc.html用户名密码就是配置文件中的结果如图 1.6.2 使用 实体类使用Schema 注解在mybatis-plus选择的话会自动生成 Conntroller 层使用 Tag(name 用户接口) RestController RequestMapping(/user) public class UserController {Autowiredprivate UserService userService; /*** 用户列表分页* param pageSize 每页显示的条数* param currentPage 要查询的页* param name 用户姓名* return ResultPageResultBeanListUser*/GetMapping(/pageList)Operation(summary 用户列表分页查询)Parameters({Parameter(name Authorization, in ParameterIn.HEADER, required true, description token),Parameter(name pageSize, required true, description 每页显示的条数),Parameter(name currentPage, required true, description 要查询的页),Parameter(name name, description 用户姓名, required false)})public ResultPageResultBeanUser pageList(RequestParam int pageSize, RequestParam int currentPage, Nullable RequestParam String name) {IPageUser page userService.pageList(pageSize, currentPage, name);if (page null) {return Result.error(查询失败);}//PageResultBeanUser pageResultBean new PageResultBeanUser(page.getTotal(), page.getRecords());return Result.success(PageResultBean.getInstance(page.getTotal(), page.getRecords()));} }1.7 数据交互处理 1.7.1 响应数据封装公共返回数据类 封装返回数据封装类放到common包下 package com.buzhisuoyun.base_manage.common;import io.swagger.v3.oas.annotations.media.Schema;public class ResultT {Schema(description 业务状态码 0成功 1: 失败)private int code; // 业务状态码 0成功 1: 失败Schema(description 提示信息)private String message; // 提示信息Schema(description 返回数据)private T data; // 响应数据public Result(int code, String message, T data) {this.code code;this.message message;this.data data;}// 操作成功返回响应结果带响应数据public static E ResultE success(E data) {return new Result(0, 操作成功, data);}public static E ResultE success() {return new Result(0, 操作成功, null);}public static E ResultE error(String message) {return new Result(1, message, null);}public int getCode() {return code;}public void setCode(int code) {this.code code;}public String getMessage() {return message;}public void setMessage(String message) {this.message message;}public T getData() {return data;}public void setData(T data) {this.data data;}Overridepublic String toString() {return Result{ code code , message message , data data };} }1.7.2 分页查询返回数据封装 封装分页查询数据放到common包下 package com.buzhisuoyun.base_manage.common;import io.swagger.v3.oas.annotations.media.Schema;import java.util.List;public class PageResultBeanT {Schema(description 数据总条数)private Long total;Schema(description 当前页数据集合)private ListT items;public PageResultBean() {}public PageResultBean(Long total, ListT items) {this.total total;this.items items;}public static E PageResultBeanE getInstance(Long total, ListE items) {return new PageResultBean(total, items);}public Long getTotal() {return total;}public void setTotal(Long total) {this.total total;}public ListT getItems() {return items;}public void setItems(ListT items) {this.items items;} }1.8 全局异常处理 创建xception包在包下放全局异常处理类GlobalExceptionHandler.java类名放置 位置可以随意为便于分类整理 同类包放到一个包下 使用springboot RestControllerAdvice 注解配置 package com.buzhisuoyun.base_manage.exception;import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice;// 全局异常处理 RestControllerAdvice public class GlobalExceptionHandler {private final Logger logger LoggerFactory.getLogger(GlobalExceptionHandler.class);ExceptionHandler(Exception.class)public ResultString handlerException(Exception e) {logger.warn(e.getMessage());return Result.error(StringUtils.hasLength(e.getMessage()) ? e.getMessage() : 操作失败);} }1.9 整合JWT生成token 引入依赖 !-- jwt --dependencygroupIdcom.auth0/groupIdartifactIdjava-jwt/artifactIdversion4.4.0/version/dependency封装工具类 放到utils包下 package com.buzhisuoyun.base_manage.utils;import com.auth0.jwt.JWT; import com.auth0.jwt.algorithms.Algorithm;import java.util.Date; import java.util.Map;public class JwtUtil {private static final String KEY buzhisuoyun; // 密钥// 接收数据生成token并返回public static String getToken(MapString, Object claims) {return JWT.create().withClaim(claims, claims).withExpiresAt(new Date(System.currentTimeMillis() 1000 * 60 * 60)) // 失效时间1小时.sign(Algorithm.HMAC256(KEY));}// 接收token,验证并返回数据public static MapString, Object parseToken(String token) {return JWT.require(Algorithm.HMAC256(KEY)).build().verify(token).getClaim(claims).asMap();} }1.10 封装ThreadLocal 工具类 因项目使用前后端分离使用ThreadLocal 线程变量存储用户登录信息替代session package com.buzhisuoyun.base_manage.utils;public class ThreadLocalUtil {// 提供ThreadLocal 对象private static final ThreadLocalObject THREAD_LOCAL new ThreadLocal();// 获取存储值public static T T get() {return (T) THREAD_LOCAL.get();}// 存储值public static void set(Object value) {THREAD_LOCAL.set(value);}// 清除THREAD_LOCAL 防止内存泄漏public static void remove() {THREAD_LOCAL.remove();} }1.11 MD5封装 package com.buzhisuoyun.base_manage.utils;import java.security.MessageDigest; import java.security.NoSuchAlgorithmException;public class Md5Util {/*** 默认的密码字符串组合用来将字节转换成 16 进制表示的字符,apache校验下载的文件的正确性用的就是默认的这个组合*/protected static char hexDigits[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f};protected static MessageDigest messagedigest null;static {try {messagedigest MessageDigest.getInstance(MD5);} catch (NoSuchAlgorithmException nsaex) {System.err.println(Md5Util.class.getName() 初始化失败MessageDigest不支持MD5Util。);nsaex.printStackTrace();}}/*** 生成字符串的md5校验值** param s* return*/public static String getMD5String(String s) {return getMD5String(s.getBytes());}/*** 判断字符串的md5校验码是否与一个已知的md5码相匹配** param password 要校验的字符串* param md5PwdStr 已知的md5校验码* return*/public static boolean checkPassword(String password, String md5PwdStr) {String s getMD5String(password);return s.equals(md5PwdStr);}public static String getMD5String(byte[] bytes) {messagedigest.update(bytes);return bufferToHex(messagedigest.digest());}private static String bufferToHex(byte bytes[]) {return bufferToHex(bytes, 0, bytes.length);}private static String bufferToHex(byte bytes[], int m, int n) {StringBuffer stringbuffer new StringBuffer(2 * n);int k m n;for (int l m; l k; l) {appendHexPair(bytes[l], stringbuffer);}return stringbuffer.toString();}private static void appendHexPair(byte bt, StringBuffer stringbuffer) {char c0 hexDigits[(bt 0xf0) 4];// 取字节中高 4 位的数字转换, // 为逻辑右移将符号位一起右移,此处未发现两种符号有何不同char c1 hexDigits[bt 0xf];// 取字节中低 4 位的数字转换stringbuffer.append(c0);stringbuffer.append(c1);}// 测试public static void main(String[] args) {System.out.println(Md5Util.getMD5String(admin));}}1.12登录验证拦截 1、创建包interceptors在包下配置登录拦截器 package com.buzhisuoyun.base_manage.interceptors;import com.buzhisuoyun.base_manage.utils.JwtUtil; import com.buzhisuoyun.base_manage.utils.ThreadLocalUtil; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor;import java.util.Map;Component public class LoginInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 获取tokenString token request.getHeader(Authorization);// 验证tokentry {MapString, Object claims JwtUtil.parseToken(token);// 存储业务信息到线程变量ThreadLocalUtil.set(claims);// 放行拦截return true;} catch (Exception e) {// 登录信息异常或未登录http响应状态码为401response.setStatus(401);// 拦截请求return false;}}Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 清除ThreadLocal业务数据ThreadLocalUtil.remove();} }2、在config包下创建WebConfig配置类注册登录拦截器 package com.buzhisuoyun.base_manage.config;import com.buzhisuoyun.base_manage.interceptors.LoginInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.util.ArrayList; import java.util.List;Configuration public class WebConfig implements WebMvcConfigurer {Autowiredprivate LoginInterceptor loginInterceptor;Overridepublic void addInterceptors(InterceptorRegistry registry) {// 配置放行资源// 无需拦截的接口集合ListString ignorePath new ArrayList();// knife4j(swagger)ignorePath.add(/swagger-resources/**);ignorePath.add(/doc.html);ignorePath.add(/v3/**);ignorePath.add(/webjars/**);ignorePath.add(/static/**);ignorePath.add(/templates/**);ignorePath.add(/error);// 登录页面ignorePath.add(/user/login);registry.addInterceptor(loginInterceptor).excludePathPatterns(ignorePath);} }1.13 登录和获取当前用户信息接口处理 PostMapping(/login)Operation(summary 用户登录)Parameters({Parameter(name loginName, description 登录名, required true, schema Schema(type sting)),Parameter(name password, description 密码, required true, schema Schema(type sting))})public ResultString login(RequestBody User user) {if (user null || .equals(user.getLoginName()) || user.getLoginName() null || .equals(user.getPassword()) || user.getPassword() null) {return Result.error(用户名密码不能为空);}// 检验用户名是否存在User eruser userService.findByLoginName(user.getLoginName());if (eruser null) {return Result.error(用户名不存在);}// 检验用户密码是否正确if (Md5Util.getMD5String(user.getPassword()).equals(eruser.getPassword())) {MapString, Object claims new HashMap();claims.put(id, eruser.getId());claims.put(name, eruser.getName());claims.put(loginName, eruser.getLoginName());String token JwtUtil.getToken(claims);return Result.success(token);}return Result.error(密码错误);}/*** 获取当前登录用户信息* return User*/GetMapping(/currentUser)Operation(summary 获取当前登录用户信息)Parameter(name Authorization, in ParameterIn.HEADER, required true, description token)public ResultUser getCurrentUser() {MapString, Object userSession ThreadLocalUtil.get();int id (int) userSession.get(id);User user userService.getUserById(id);if (user ! null) {return Result.success(user);}return Result.error(用户状态异常);}因为是做简单后端项目搭建所以token存在一定问题如在修改用户密码后必须强制重新登录或采用redis缓存token,同时验证浏览器token和用户token或采用第三方认证中心解决等 项目工程结构如图 2. 前端项目搭建 2.1 环境准备 - node安装 - vscode安装2.2 创建Vue3项目 在将要存放vue3项目的路径打开cmd, 使用以下命令创建项目 npm init vuelatest此时项目创建完成vscode打开项目目录在资源目录空白右键打开终端 执行命令 npm install安装依赖等待安装完成后执行 npm run dev 运行项目 访问路径可访问项目 在终端ctrl c 可停止运行项目 项目描述如图图引自黑马开源教程PPT 2.3 项目搭建准备 说明项目中使用组合式API 删掉components下所有文件删除App.vue文件不需要的东西最后如下所示 script setup/scripttemplaterouter-view/router-view /templatestyle scoped/style2.4 Element Plus 安装使用 安装 npm install element-plus --save 引入在main.js中引入Element Plus参照官方文档https://element.eleme.cn/#/zh-CN/component/quickstart import { createApp } from ‘vue’ import ElementPlus from ‘element-plus’ import ‘element-plus/dist/index.css’ import App from ‘./App.vue’ const app createApp(App) app.use(ElementPlus) app.mount(‘#app’) 使用 访问Element官方文档复制组件代码修改调整 2.5 axios 安装使用 2.5.1 安装 npm install axios2.5.2 配置创建实例配置请求、响应拦截器 在src目录下新建 utils, 并在utils 下创建request.js 进行axios配置 // 请求配置import axios from axios;// 定义公共前缀创建请求实例 // const baseUrl http://localhost:8080; const baseURL /api/; const instance axios.create({baseURL})import { ElMessage } from element-plus import { useTokenStore } from /stores/token.js // 配置请求拦截器 instance.interceptors.request.use((config) {// 请求前回调// 添加tokenconst tokenStore useTokenStore()// 判断有无tokenif (tokenStore.token) {config.headers.Authorization tokenStore.token}return config},(err) {// 请求错误的回调Promise.reject(err)} )import router from /router; // 添加响应拦截器 instance.interceptors.response.use(result {// 判断业务状态码if (result.data.code 0) {return result.data;}// 操作失败ElMessage.error(result.data.message ? result.data.message : 服务异常)// 异步操作的状态转换为失败return Promise.reject(result.data)},err {// 判断响应状态码 401为未登录提示登录并跳转到登录页面if (err.response.status 401) {ElMessage.error(请先登录)router.push(/login)} else {ElMessage.error(服务异常)}// 异步操作的状态转换为失败return Promise.reject(err) } )export default instance2.5.3 配置跨域 在vite.config.js 中defineConfig配置代理实现跨域 server: {proxy: {/api: { // 获取路径中包含了/api的请求target: http://localhost:9999, // 服务端地址changeOrigin: true, // 修改源rewrite:(path) path.replace(/^/api/, ) // api 替换为 }}}2.6 Vue Router 安装使用 安装 npm install vue-router4 在src/router/index.js中创建路由器并导出 // 导入vue-router import {createRouter, createWebHistory} from ‘vue-router’ // 导入组件 import LoginVue from ‘/views/Login.vue’ import LayoutVue from ‘/views/Layout.vue’ import UserList from ‘/views/user/UserList.vue’ import EditPassword from ‘/views/user/EditPassword.vue’ import DisplayUser from ‘/views/user/DisplayUser.vue’ // 定义路由关系 const routes [ {path: ‘/login’, component: LoginVue}, { path: ‘/’, component: LayoutVue, redirect: ‘’, children: [ {path: ‘/user/userlist’, name: “/user/userlist”, component: UserList, meta: { title: “用户列表” },}, {path: ‘/user/editpassword’, name: “/user/editpassword”, component: EditPassword, meta: { title: “修改密码” } }, {path: ‘/user/displayuser’, name: “/user/displayuser”, component: DisplayUser, meta: { title: “个人信息” }} ] } ] // 创建路由器 const router createRouter({ history: createWebHistory(), routes: routes }) export default router 在vue应用实例中使用vue-router 在main.js 中 import router from ‘/router’ app.use(router) 声明router-view标签展示组件内容 在app.vue 中 2.7 Pinia状态管理库 安装 npm install pinia 2.7.1 Pinia持久化插件-persist 安装persist npm install pinia-persistedstate-plugin 在pinia中使用persist main.js import {createPersistedState} from’pinia-persistedstate-plugin’ const persist createPersistedState() pinia.use(persist) 定义状态Store时指定持久化配置参数 在src/stores/下定义token.js和userInfo.js 用来存储token和用户相关信息 token.js // 定义 store import { defineStore } from “pinia” import {ref} from ‘vue’ /* 第一个参数:名字,唯一性 第二个参数:函数,函数的内部可以定义状态的所有内容 返回值: 函数*/ export const useTokenStore defineStore(‘token’, () { // 响应式变量 const token ref(‘’) // 修改token值函数 const setToken (newToken) {token.value newToken }// 移除token值函数 const removeToke () {token.value }return {token, setToken, removeToke }}, { persist: true // 持久化存储 } ) userInfo.js import { defineStore } from “pinia” import {ref} from ‘vue’ const useUserInfoStore defineStore(‘userInfo’, () { const info ref({}) const setInfo (newInfo) {info.value newInfo }const removeInfo () {info.value {} }return {info, setInfo, removeInfo}}, { persist: true } ) export default useUserInfoStore; 在组件中使用store 示例 import {userLoginService} from ‘/api/user.js’ import {useTokenStore} from ‘/stores/token.js’ import {useRouter} from ‘vue-router’ const router useRouter() const tokenStore useTokenStore(); const login async (){ // 校验表单 if (!ruleFormRef.value) return console.log(“校验”) await ruleFormRef.value.validate(async (valid) { if (valid) { console.log(“校验成功”) // 调用接口,完成登录 let result await userLoginService(registerData.value); /* if(result.code0){ alert(result.msg? result.msg : ‘登录成功’) }else{ alert(‘登录失败’) } */ //alert(result.msg? result.msg : ‘登录成功’) ElMessage.success(result.msg ? result.msg : ‘登录成功’) //token存储到pinia中 tokenStore.setToken(result.data) //跳转到首页 路由完成跳转 router.push(‘/’) } else { console.log(“校验失败”) } }) } // 配置请求拦截器 instance.interceptors.request.use( (config) { // 请求前回调 // 添加token const tokenStore useTokenStore() // 判断有无token if (tokenStore.token) { config.headers.Authorization tokenStore.token } return config }, (err) { // 请求错误的回调 Promise.reject(err) } ) 2.8 搭建管理页面基础框架 2.8.1 在src下创建api目录次目录存放请求http方法的封装创建user.js 里边写封装请求方法 import request from /utils/request.js// 登录接口调用函数 export const userLoginService (loginData) {return request.post(/user/login, loginData) }// 获取当前登录用户信息 export const currentUserService () {return request.get(/user/currentUser) }// 获取所有用户信息 export const allUserService () {return request.get(/user/userList) }// 分页查询 export const pageListService (pageParam) {return request.get(/user/pageList, {params: pageParam}) }// 新增用户 export const addUserService (addData) {return request.post(/user/add, addData) }// 根据id获取用户信息 export const getUserById (id) {return request.get(/user/getuserById, {params: id}) }// 修改用户信息 export const updateUserService (data) {return request.put(/user/update, data) }// 删除用户 export const deleteByIdService (id) {console.log(deleteRequestid:, id)return request.delete(/user/delete/ id) }2.8.2 登录页面 安装 npm install sass -D 在src下创建views目录,用于存放vue页面组件 登录 Login.vue script setup import { User, Lock } from element-plus/icons-vue import { ref, reactive } from vue import { ElMessage } from element-plus //定义数据模型 const registerData ref({loginName: admin,password:admin,rePassword: })// 定义表单组件的引用 const ruleFormRef ref(null)//定义表单校验规则 const rules ref({loginName: [{ required: true, message: 请输入用户名, trigger: blur },{ min: 5, max: 16, message: 长度为5~16位非空字符, trigger: blur }],password: [{ required: true, message: 请输入密码, trigger: blur },{ min: 5, max: 16, 2: 长度为5~16位非空字符, trigger: blur }] })//绑定数据,复用注册表单的数据模型 //表单数据校验 //登录函数 import {userLoginService} from /api/user.js import {useTokenStore} from /stores/token.js import {useRouter} from vue-router const router useRouter() const tokenStore useTokenStore(); const login async (){// 校验表单if (!ruleFormRef.value) returnconsole.log(校验)await ruleFormRef.value.validate(async (valid) {if (valid) {console.log(校验成功)// 调用接口,完成登录let result await userLoginService(registerData.value);/* if(result.code0){alert(result.msg? result.msg : 登录成功)}else{alert(登录失败)} *///alert(result.msg? result.msg : 登录成功)ElMessage.success(result.msg ? result.msg : 登录成功)//token存储到pinia中tokenStore.setToken(result.data)//跳转到首页 路由完成跳转router.push(/)} else {console.log(校验失败)}}) }//定义函数,清空数据模型的数据 const clearRegisterData (){registerData.value{loginName: ,password:,rePassword:} } /scripttemplateel-row classlogin-pageel-col :span12 classbg/el-colel-col :span6 :offset3 classform!-- 登录表单 --el-form refruleFormRef :modelregisterData sizelarge autocompleteoff :rulesrulesel-form-itemh1登录/h1/el-form-itemel-form-item proploginNameel-input :prefix-iconUser placeholder请输入用户名 v-modelregisterData.loginName/el-input/el-form-itemel-form-item proppasswordel-input namepassword :prefix-iconLock typepassword placeholder请输入密码 v-modelregisterData.password/el-input/el-form-itemel-form-item classflexdiv classflexel-checkbox记住我/el-checkbox!-- el-link typeprimary :underlinefalse忘记密码/el-link --/div/el-form-item!-- 登录按钮 --el-form-itemel-button classbutton typeprimary auto-insert-space clicklogin登录/el-button/el-form-item/el-form/el-col/el-row /templatestyle langscss scoped /* 样式 */ .login-page {height: 100vh;background-color: #fff;.bg {background: url(/assets/login_bg.jpg) no-repeat center / cover;border-radius: 0 20px 20px 0;}.form {display: flex;flex-direction: column;justify-content: center;user-select: none;.title {margin: 0 auto;}.button {width: 100%;}.flex {width: 100%;display: flex;justify-content: space-between;}} } /style2.8.3 布局页面 Layout .vue 项目结构 3.项目代码 https://download.csdn.net/download/qq_51355375/89085020 此项目不包含动态路由菜单权限部分 如需要可参考 https://blog.csdn.net/qq_51355375/article/details/139722876
http://www.hkea.cn/news/14297136/

相关文章:

  • 建设网站需要注册证书吗怎么在网上做广告
  • 微网站建设公司哪家好东莞大朗网站设计
  • wix做的网站 网址是什么施工员证查询官方网站
  • 医疗网站前置备案如何判断网站是响应式的还是
  • 怎么做招聘网站的调研相城seo网站优化软件
  • 网站建设 策划方案邵阳市城乡建设厅网站
  • 襄阳网站建设开发办公空间设计网站
  • 美食网站开发与设计文献综述wordpress迁移器
  • 网站设计第一步怎么做wordpress不显示全文
  • 网站开发需会的课程如何推广自己的产品
  • 创造与魔法官方网站做自己喜欢的事做淘宝内部优惠券网站要钱么
  • 一站式网站搭建wordpress设置超链接
  • 邯郸wap网站建设定制手机网站
  • 更改网站的布局电商网站设计理念
  • 怎么建立自己网站免费商标设计网站
  • 怎么在后台设置网站的关键词网站建设合同注意事项
  • 做网站赚钱吗 怎么赚苏州有做网站的公司吗
  • wap网站搜索做视频投稿赚钱的网站
  • 安徽弘泰建设管理有限公司网站深圳建设局网站打不开
  • 做网站的流程方法西安专业网站设计
  • 云南省建设厅官方网站证书站长之家域名查询鹿少女
  • 朝阳免费网站制作汕头建设学校的网站
  • 5118素材网站wordpress音乐主题推荐
  • 沙田镇网站建设公司网站建设属开票核定税种
  • 哪里有网站制作技术nike官网宣传片
  • 杭州市城乡建设 网站网站使用引导
  • 潍坊做网站的公司悦昂网站建设
  • 做网站赚钱 2017一个域名绑定多个网站
  • 三亚北京网站建设核桃编程怎么报名网课
  • 县城做二手车网站海飞丝网站建设中面临的技术问题_并提出可行的技术解决方案