权限管理的概述以及vue开发前端的路由、菜单、按钮权限控制实现方案

在这里插入图片描述

1. 权限管理概念

1.1 权限定义

权限管理是确保用户只能访问被授权资源的机制。在计算机系统中,权限通常指对特定数据或功能的访问权。权限的设置和控制对于保护数据安全和系统安全至关重要。

1.2 前端权限控制重要性

前端权限控制是用户与应用交互的第一道防线。它不仅能够提升用户体验,通过隐藏未授权的功能减少用户的困惑,还能作为后端权限控制的补充,降低未授权访问的风险。有效的前端权限控制可以减少不必要的服务器请求,提高应用性能,并增强应用的安全性。

2. 前端权限控制实现策略

2.1 角色与权限的映射

在前端实现权限控制,首先需要定义角色与权限的映射关系。这通常通过角色-权限矩阵来实现,每个角色分配一组权限,用户根据其角色获得相应的权限。

2.2 动态路由控制

根据用户的角色动态生成路由,确保用户只能访问其拥有权限的页面。这可以通过在路由配置中添加角色信息,并在应用启动时根据用户角色动态加载路由来实现。

2.3 按钮级别的权限控制

对于按钮级别的权限控制,可以在界面组件中使用权限标识来控制显示。例如,使用 v-if 指令结合用户权限来判断是否渲染某个按钮。

2.4 请求拦截

在前端使用请求拦截器,根据用户权限对请求进行拦截,防止未授权的请求发送到服务器。例如,可以在请求头中添加权限标识,并在后端进行验证。

2.5 权限缓存与更新

用户权限应该被缓存以减少频繁的权限验证请求,同时需要提供权限更新机制,以响应权限变更的场景。

3. Vue中的权限管理实现

3.1 Vue Router 路由守卫

利用 Vue Router 的路由守卫功能,可以实现基于角色的路由访问控制。通过 beforeEachbeforeEnter 守卫,可以判断当前用户的角色,并据此允许或重定向路由。

3.2 Vuex 管理用户状态

使用 Vuex 存储和管理用户的角色和权限信息,可以在全局范围内方便地访问这些信息,并在需要时进行状态更新。

3.3 自定义指令

创建自定义指令,如 v-permission,用于简化按钮级别的权限控制。通过该指令,可以直接在元素上声明所需的权限,指令内部处理是否显示该元素的逻辑。

3.4 与后端API的协作

前端权限控制需要与后端API紧密协作,后端API需要提供用户角色和权限信息,并在处理请求时进行权限验证。

3.5 权限变更的处理

实现一个机制来监听和响应权限的变更,例如,当用户角色更新后,前端需要重新加载用户的权限信息,并更新界面上的权限控制。

2. 前端权限控制策略

2.1 接口权限控制

接口权限控制是前端权限管理的基础,通常采用JWT(Json Web Tokens)或者OAuth等认证机制来实现。

  • 认证机制:用户登录后,服务端生成一个包含用户身份信息的token,前端在每次请求时将token发送给后端进行验证。
  • 请求拦截器:在前端框架(如Vue)中,可以使用请求拦截器来统一处理请求头的token添加,简化代码。
  • 响应拦截器:通过响应拦截器来处理token过期、无效等问题,如在Vue中使用axios拦截器:
    axios.interceptors.request.use(config => {config.headers['Authorization'] = `Bearer ${getToken()}`;return config;
    });
    axios.interceptors.response.use(response => {if (response.data.code === 401) {// token过期处理逻辑}return response;
    }, error => {if (error.response.status === 401) {// token过期处理逻辑}return Promise.reject(error);
    });
    

2.2 路由权限控制

路由权限控制是实现前端权限管理的关键环节,Vue中通常通过路由守卫来实现。

  • 路由守卫:在Vue Router中,可以使用全局路由守卫或者单个路由的守卫来控制访问权限。
  • 动态路由:根据用户的角色和权限动态生成路由,只有用户有权限访问的路由才会被渲染。
  • 路由元信息:在路由配置中添加元信息字段,如rolespermission,用于标识该路由需要的权限。
  • 示例代码
    const router = new VueRouter({routes: [{path: '/admin',component: Admin,beforeEnter: (to, from, next) => {if (hasRole('admin')) {next();} else {next({ path: '/403' });}}},{path: '/403',component: () => import('@/views/403.vue')}]
    });
    

2.3 按钮权限控制

按钮权限控制是权限管理中粒度更细的控制,通常在视图层进行控制。

  • v-if指令:在Vue中,可以使用v-if指令来控制按钮的显示,根据用户权限动态渲染按钮。
  • 自定义指令:可以创建一个自定义指令,如v-has,来简化按钮权限的判断逻辑。
  • 示例代码
    Vue.directive('has', {bind: function (el, binding, vnode) {const { value } = binding;const permissions = vnode.context.$route.meta.btnPermissions;if (!value || !permissions.includes(value)) {el.parentNode.removeChild(el);}}
    });
    
    使用:
    <el-button @click="editClick" type="primary" v-has="'edit'">编辑</el-button>
    

2.4 菜单权限控制

菜单权限控制是前端权限管理的另一个重要方面,通常与路由权限控制相结合。

  • 菜单动态渲染:根据用户的角色和权限动态生成菜单项,只有用户有权限看到的菜单项才会被渲染。
  • 后端配合:后端需要提供用户权限信息,前端根据这些信息来控制菜单的显示。
  • 示例代码
    const menuData = await getUserInfo();
    const accessMenu = menuData.accessMenu;
    const routerMap = accessMenu.map(item => ({path: item.path,component: () => import(`@/views/${item.component}.vue`),name: item.name,meta: { roles: item.roles }
    }));
    router.addRoutes(routerMap);
    

2.5 请求控制

请求控制是前端权限管理的最后一道防线,用于拦截越权请求。

  • 请求拦截器:在发送请求时,检查用户是否具有相应的权限,如果没有,则拦截请求。
  • 示例代码
    axios.interceptors.request.use(config => {const userPermissions = getUserPermissions();const requiredPermission = config.url.match(/\/(api\/.*)\//)[1];if (!userPermissions.includes(requiredPermission)) {return Promise.reject(new Error('Unauthorized'));}return config;
    });
    

3. Vue中的路由权限控制实现

3.1 路由守卫

路由守卫是Vue Router中用于控制路由跳转的重要机制,可以基于用户权限来控制路由的访问。

  • 全局守卫:在Vue Router实例中使用beforeEachbeforeEnter等方法设置全局守卫,对所有路由跳转进行前置检查。
  • 权限拦截:通过判断用户的角色或权限,决定是否允许访问特定路由。例如,只有管理员角色可以访问管理后台。
router.beforeEach((to, from, next) => {const userRole = localStorage.getItem('userRole'); // 假设用户角色存储在本地存储中if (to.matched.some(record => record.meta.requiresAdmin)) {if (userRole !== 'admin') {next('/unauthorized'); // 重定向到无权限访问页面} else {next(); // 管理员可以访问}} else {next(); // 非管理员路由,直接访问}
});

3.2 动态路由加载

动态路由加载是指根据用户权限动态地加载和显示路由,确保用户只能看到和访问他们有权限的路由。

  • 后端角色信息:从后端获取用户的角色和权限信息,通常在用户登录后由后端返回。
  • 动态添加路由:根据用户的角色和权限信息,动态构建和添加路由到Vue Router中。
// 假设从后端获取到的路由权限数据
const permissions = ['dashboard', 'user', 'profile'];// 根据权限动态添加路由
permissions.forEach(permission => {if (permission === 'dashboard') {router.addRoute({path: '/dashboard',component: Dashboard,name: 'dashboard'});}// 根据其他权限添加更多路由...
});

通过这种方式,可以确保只有用户有权限访问的路由才会被加载和显示,实现按钮级别的权限控制。同时,这也有助于提升应用的性能,因为只有必要的路由组件会被加载。

4. 按钮级别权限控制策略

4.1 使用v-if进行按钮权限控制

在Vue中,可以通过v-if指令来控制按钮的显示,从而实现按钮级别的权限控制。这种方法简单直接,适用于权限控制逻辑较为简单的情况。

  • 实现方式:在按钮的v-if指令中加入权限判断逻辑,只有当用户拥有相应权限时,按钮才会显示。

  • 示例代码

    <template><el-buttonv-if="hasPermission('edit')"@click="editClick"type="primary">编辑</el-button>
    </template><script>
    export default {data() {return {// 假设用户权限列表permissions: ['edit', 'delete']};},methods: {hasPermission(permission) {return this.permissions.includes(permission);},editClick() {// 编辑操作}}
    };
    </script>
    
  • 优点:实现简单,易于理解和维护。

  • 缺点:随着权限逻辑的复杂化,可能会导致模板中的逻辑过于复杂,难以维护。

4.2 自定义指令实现按钮权限控制

自定义指令是Vue中一种强大的功能,可以用来封装和复用DOM操作逻辑。通过自定义指令,可以实现更灵活和可复用的按钮权限控制。

  • 实现方式:创建一个全局或局部的自定义指令,用于判断用户是否具有执行按钮操作的权限。

  • 示例代码

    <template><el-buttonv-has="['edit']"@click="editClick"type="primary">编辑</el-button>
    </template><script>
    import Vue from 'vue';Vue.directive('has', {bind(el, binding, vnode) {const { value } = binding;const permissions = vnode.context.$route.meta.permissions || [];if (!permissions.includes(value)) {el.parentNode.removeChild(el);}}
    });export default {data() {return {// 假设当前路由的权限列表routePermissions: ['edit', 'view']};},methods: {editClick() {// 编辑操作}}
    };
    </script>
    
  • 优点:提高了代码的复用性和可维护性,逻辑更加清晰。

  • 缺点:实现相对复杂,需要对Vue的自定义指令有较深的理解。

  • 权限数据的获取:权限数据可以通过后端接口获取,并存储在Vuex或组件的data中。在路由守卫或组件的created钩子中进行初始化。

  • 权限数据的存储:建议将权限数据存储在Vuex的state中,这样可以在全局范围内访问和使用。

  • 权限数据的更新:在用户登录或权限变更时,需要更新存储的权限数据,以确保权限控制的准确性。

通过上述两种策略,可以实现Vue应用中按钮级别的权限控制,确保用户只能看到和操作他们有权限的内容。

5. 菜单权限控制

5.1 菜单与路由分离

在Vue应用中,实现菜单权限控制的一种有效方法是将菜单与路由分离。这种方法的核心思想是将菜单的显示逻辑与路由的访问控制逻辑分开处理。

  • 前端定义路由信息:前端只定义路由的路径、组件和名称等基本信息,不包含任何权限信息。这样做的好处是,即使菜单信息发生变化,也不会影响路由的结构。

    {name: "login",path: "/login",component: () => import("@/pages/Login.vue")
    }
    
  • 后端返回菜单数据:菜单数据由后端服务提供,前端通过API获取菜单信息,并根据用户的角色和权限动态生成菜单。这种方式使得菜单的维护和更新更加灵活,不需要每次更改菜单时都重新编译前端代码。

  • 权限校验:在全局路由守卫中,根据用户的权限和后端返回的菜单数据,动态决定是否显示某个菜单项。如果用户没有权限访问某个菜单项,则在前端不显示该项。

  • 性能优化:由于菜单数据是动态生成的,可以利用前端缓存机制,减少对后端API的请求次数,提高应用的性能。

  • 用户体验:用户只能看到自己有权限访问的菜单项,这有助于提升用户体验,避免用户看到无法访问的菜单项而产生困惑。

5.2 后端返回菜单数据

后端返回菜单数据是实现菜单权限控制的关键步骤。后端需要根据用户的角色和权限,返回相应的菜单信息。

  • 菜单数据结构:后端返回的菜单数据通常包含菜单项的名称、路径、图标、子菜单等信息。这些信息需要与前端的路由信息相对应。

    [{"name": "home","path": "/","component": "home"},{"name": "home","path": "/userinfo","component": "userInfo"}
    ]
    
  • 权限过滤:后端在返回菜单数据时,需要根据用户的权限进行过滤,只返回用户有权限访问的菜单项。这通常涉及到对用户角色和权限的查询和判断。

  • 动态菜单生成:前端在获取到后端返回的菜单数据后,需要动态生成菜单。这可以通过递归遍历菜单数据,根据每个菜单项的路径和组件信息,动态创建路由对象。

  • 路由守卫集成:在全局路由守卫中,需要集成对菜单数据的权限校验。当用户尝试访问某个路由时,前端需要检查用户是否有权限访问该路由对应的菜单项。

  • 安全性考虑:后端在返回菜单数据时,需要确保数据的安全性,避免泄露敏感信息。同时,前端在处理菜单数据时,也需要进行安全校验,防止跨站脚本攻击(XSS)等安全问题。

通过上述方法,可以实现Vue应用中的菜单权限控制,确保用户只能访问到自己有权限的菜单项,从而提高应用的安全性和用户体验。

6. 安全性考虑

6.1 前端权限与后端权限的配合

在进行Vue权限管理时,前端和后端的紧密配合是确保系统安全性的关键。前端权限管理主要是提升用户体验和初步过滤请求,而后端权限验证则是最终的权限控制保障。

角色与权限的后端校验

  • 角色与权限数据应该在后端进行集中管理,通过数据库存储角色与权限的映射关系。
  • 用户登录后,后端根据用户的角色分配相应的权限,并生成一个包含权限信息的JWT(Json Web Tokens),随登录响应返回给前端。

前端权限的实现

  • 前端根据JWT中的权限信息动态展示菜单和按钮。使用如v-if或自定义指令v-has来控制DOM元素的显示与隐藏。
  • 前端路由守卫结合路由元信息(如meta.rolesmeta.btnPermissions)来判断用户是否有权限访问特定路由或操作。

请求拦截与响应处理

  • 使用axios拦截器在请求发出前添加权限验证,如检查JWT的合法性。
  • 响应拦截器用于处理后端返回的权限相关错误,如401未认证或403无权限,根据情况可能需要重定向到登录页或显示错误提示。

按钮级别的权限控制

  • 对于按钮级别的权限控制,可以在路由或组件的元信息中定义所需的权限。
  • 自定义指令v-has可以被用于按钮或其他元素上,通过比较当前用户权限与所需权限来决定是否渲染该元素。

安全性最佳实践

  • 避免将敏感操作的权限控制仅放在前端实现,以防被绕过。
  • 定期审计权限控制逻辑,确保没有配置错误或遗漏。
  • 对权限数据进行敏感性分类,对于高风险操作增加额外的验证机制,如二次确认或验证码。

跨域与CSRF防护

  • 在设置CORS策略时,只允许信任的域名访问资源。
  • 使用CSRF Token来防止跨站请求伪造攻击,每次表单提交或重要请求都应包含此Token。

总结

权限管理是一个多层次、多维度的工作,需要前后端共同协作,形成一套完整的安全机制。前端负责界面的展示控制和初步的权限校验,而后端则进行最终的权限判断和数据安全防护。只有两者紧密结合,才能确保应用的安全性和数据的完整性。

7. 总结

在Vue中实现权限管理,尤其是控制到按钮级别的权限,需要综合考虑前端与后端的配合,以及路由、菜单和按钮权限的控制策略。以下是对整个研究主题的总结:

7.1 权限管理的重要性

权限管理是确保应用安全性的关键环节,它能够保证用户只能访问他们被授权的资源。在Vue应用中,这通常涉及到对路由、菜单和按钮等界面元素的访问控制。

7.2 前端权限控制策略

前端权限控制主要通过以下几种方式实现:

  • 路由权限控制:通过全局路由守卫或路由元信息来控制页面访问权限。
  • 菜单权限控制:将菜单与路由分离,根据用户权限动态显示菜单项。
  • 按钮权限控制:使用v-if指令或自定义指令来控制按钮的显示与隐藏。

7.3 后端权限控制策略

后端权限控制是安全的基础,通常通过以下方式实现:

  • 接口权限验证:使用如JWT等token机制来验证用户请求。
  • 角色与权限的后端校验:确保用户请求的接口和操作符合其角色和权限。

7.4 技术实现

技术实现方面,Vue应用可以采用以下方法:

  • 使用Axios拦截器:在请求头中添加token,并在响应中处理token过期等逻辑。
  • 动态路由加载:登录后根据用户权限动态加载可访问的路由。
  • 自定义指令:创建v-has等自定义指令,简化按钮级别的权限判断。

7.5 性能与用户体验

在设计权限管理系统时,需要平衡性能和用户体验:

  • 避免过度的权限判断:减少全局路由守卫中的复杂判断逻辑,提高应用性能。
  • 用户友好的提示:对于无权限的访问请求,给予用户清晰友好的提示。

7.6 安全性

权限管理的安全性至关重要,应确保:

  • 前后端双重验证:前端控制用户界面显示,后端进行安全校验。
  • 定期的安全审计:定期检查权限控制逻辑,修复可能的安全漏洞。

7.7 可维护性与扩展性

设计权限管理系统时,应考虑到系统的可维护性与扩展性:

  • 模块化设计:将权限控制逻辑模块化,便于维护和扩展。
  • 灵活的权限配置:允许通过配置而非代码修改来调整权限设置。

通过上述总结,我们可以看到,Vue中的权限管理是一个多维度、多层次的复杂问题,需要开发者从多个角度进行综合考虑和设计。

如果这篇文章对你有所帮助,欢迎点赞、分享和留言,让更多的人受益。感谢你的细心阅读,如果你发现了任何错误或需要补充的地方,请随时告诉我,我会尽快处理。

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

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

相关文章

黑马头条Day12-项目部署_持续集成

一、今日内容介绍 1. 什么是持续集成 持续集成&#xff08;Continuous integration&#xff0c;简称CI&#xff09;&#xff0c;指的是频繁地&#xff08;一天多次&#xff09;将代码集成到主干。 持续集成的组成要素&#xff1a; 一个自动构建过程&#xff0c;从检出代码、…

jdk版本管理利器-sdkman

1.什么是sdkman&#xff1f; sdkman是一个轻量级、支持多平台的开源开发工具管理器&#xff0c;可以通过它安装任意主流发行版本&#xff08;例如OpenJDK、Kona、GraalVM等等&#xff09;的任意版本的JDK。通过下面的命令可以轻易安装sdkman: 2.安装 curl -s "https://…

什么是 5G?

什么是 5G&#xff1f; 5G 是第五代无线蜂窝技术&#xff0c;与以前的网络相比&#xff0c;它提供了更高的上传和下载速度、更一致的连接以及更高的容量。5G 比目前流行的 4G 网络更快、更可靠&#xff0c;并有可能改变我们使用互联网访问应用程序、社交网络和信息的方式。例如…

通过 WSL 2 在Windows 上挂载 Linux 磁盘

原文查看 曾为了传输或者共享不同系统的文件频繁地在 Windows 和 Linux 系统之间切换&#xff0c;效率过低&#xff0c;所以尝试通过 WSL 2 在Windows 上挂载 Linux 磁盘。 先决条件 需要在Windows 10 2004 及更高版本&#xff08;Build 19041 及更高版本&#xff09;或 Win…

Redis 缓存

安装 安装 Redis 下载&#xff1a; Releases tporadowski/redis (github.com) winr ----services.msc-----将redis 设置为手动(只是学习&#xff0c;如果经常用可以设置为自动) 安装 redis-py 库 pip install redis-py Redis 和 StrictRedis redis-py 提供 Redis 和 Str…

UDP通信 单播,广播,组播

UDP通信实现 #include <sys/types.h> #include <sys/socket.h> ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); - 参数&#xff1a; struct sockaddr *src_addr, socklen_t *addrlen…

vue基础3

1.推荐好用的第三方框架 BootCDN - Bootstrap 中文网开源项目免费 CDN 加速服务 1.moment.js 2.dayjs 2.收集表达数据 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>Document</title><…

MyBatis-Plus自动生成代码

目录 前言一. 什么是 MyBatis-Plus1. Mybatis-Plus 的特点2. Mybatis-Plus 结构二. MyBatis-Plus 自动生成步骤1. 数据库准备2. 环境准备(1) 创建一个空的 Spring Boot 工程(2) 导入pom依赖(3) 编辑application.yml文件(4) 在启动类加入 @MapperScan 注解3. 配置代码4. 运行三.…

数据库安全:MySQL安全配置,MySQL安全基线检查加固

「作者简介」:冬奥会网络安全中国代表队,CSDN Top100,就职奇安信多年,以实战工作为基础著作 《网络安全自学教程》,适合基础薄弱的同学系统化的学习网络安全,用最短的时间掌握最核心的技术。 这一章节我们需要知道MySQL的安全基线标准和加固方式。 MySQL基线检查 1、更新…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 围棋的气(100分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 🍿 最新华为OD机试D卷目录,全、新、准,题目覆盖率达 95% 以上,支持题目在线…

unity3d:TabView,UGUI多标签页组件,TreeView树状展开菜单

概述 1.最外层DataForm为空壳编辑数据用。可以有多个DataForm&#xff0c;例如福利DataForm&#xff0c;抽奖DataForm 2.Menu层为左边栏层&#xff0c;每个DataForm可以使用不同样式的MenuForm预制体 3.DataForm中使用ReorderList&#xff0c;可排列配置 4.有定位功能&#xf…

stl-set

目录 目录 内部自动有序、不含重复元素 关于能不能自己造一个cmp&#xff0c;还挺复杂。 访问&#xff1a;只能用迭代器且受限 添加元素&#xff1a;没有pushback&#xff0c;用insert 复杂度&#xff1a;ologn ​编辑 查找元素find&#xff08;&#xff09;&#xff1…

C++-入门(下)

一、前言&#xff1a; 目标&#xff1a; 1. C 关键字 2. 命名空间 3. C 输入 & 输出 4. 缺省参数 5. 函数重载 6. 引用 7. 内联函数 8. auto 关键字 (C11) 9. 基于范围的 for 循环 (C11) 10. 指针空值 ---nullptr(C11) 二、目标的实现&#xff1a; 6. 引用&#xff1a;…

后端开发工程师vue2初识的学习

博客主页&#xff1a;音符犹如代码系列专栏&#xff1a;JavaWeb关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 什么是Vue&#xff1f; Vue &#xff08;通常指 Vue.js&#xff09;是一个用…

Mybatis批量更新数据库错误

问题&#xff1a;记录一次使用Mybatis批量更新数据库的错误&#xff0c;错误信息&#xff0c;Error updating database. Cause: org.postgresql.util.PSQLException: 错误: 字段 "update_time" 的类型为 timestamp without time zone, 但表达式的类型为 text 建议&am…

【Unity动画】Animation Sequencer:动画制作的革新工具

在Unity游戏开发中&#xff0c;动画是提升玩家体验的关键因素。传统的动画制作方式往往耗时且复杂&#xff0c;但有了Animation Sequencer&#xff0c;这一过程将变得更加直观和高效。本文将介绍Animation Sequencer这一视觉工具&#xff0c;探讨其如何帮助开发者在Unity编辑器…

Ubuntu 20.04.6 安装 Elasticsearch

1.准备 -- 系统更新 sudo apt update sudo apt upgrade -- 安装vim 文本编辑器 sudo apt install vim-- jdk 版本确认 java -versionjdk 安装可以参照&#xff1a;https://blog.csdn.net/CsethCRM/article/details/140768670 2.官方下载Elasticsearch 官方地址&#xff1a;h…

Linux源码阅读笔记14-IO体系结构与访问设备

IO体系结构 与外设通信通常称为输入输出&#xff0c;一般缩写为I/O。在实现外设IO的时候&#xff0c;内核必须处理三个可能出现的问题&#xff1a; 必须根据具体的设备类型和模型&#xff0c;使用各种方法对硬件寻址。内核必须向用户应用程序和系统工具提供访问各种设备的方法…

maven引入了jar包但在class文件里找不到jar包里的类

在工作当中遇到的这个问题&#xff0c;别人引入的jar包&#xff0c;我代码里报错 maven clean 和 maven install 都不管用 检查过了pom文件 检查了maven仓库路径下是否有这个cn.hutool的jar包 都没有找到问题 最终解决办法是手动引入 步骤一&#xff1a;点击左上角file->…

Golang | Leetcode Golang题解之第290题单词规律

题目&#xff1a; 题解&#xff1a; func wordPattern(pattern string, s string) bool {word2ch : map[string]byte{}ch2word : map[byte]string{}words : strings.Split(s, " ")if len(pattern) ! len(words) {return false}for i, word : range words {ch : patt…