Vue3 路由权限管理:基于角色的路由生成与访问控制
Vue3 路由权限管理:基于角色的路由生成与访问控制
一、核心概念
1.1 大致流程思路:
用户在登录完成的时候,后端给出一个此登录用户对应的角色名字,此时可以将这个用户的角色存起来(vuex/pinia)中,在设置路由时的meta字段中设置的roles属性如:roles: ['admin', 'accountA', 'accountB']----这就是每个页面能访问的角色名。至此为止,用户的角色名字我们拿到了,每个页面能访问的角色名字我们也知道了,接下来只需要去判断当前用户的角色名是否包含这些权限即可—这就需要交给导航守卫了:router.beforeEach((to, from, next) => {})。
1.2 核心组件对比表
| 组件 | 作用 | 示例 | 特点 |
|---|---|---|---|
| 静态路由 | 基础公共路由 | 登录页/404页 | 无需权限,初始加载 |
| 动态路由 | 权限控制路由 | 管理后台各页面 | 按需加载,角色过滤 |
| 路由守卫 | 访问控制 | beforeEach钩子 | 实时验证,安全屏障 |
| 状态管理 | 角色存储 | Vuex/Pinia | 全局共享,持久化 |
基于角色的路由权限管理系统主要包含以下几个核心部分:
-
静态路由:无需权限即可访问的路由(如登录页、404页)
-
动态路由:需要根据角色的权限进行控制是否显示的路由(如后台管理页面)。
-
角色权限配置:定义哪些角色可以访问哪些路由,如:

- 路由守卫:在路由跳转时进行权限验证
二、代码实现解析
1. 路由配置
// 静态路由 - 无需权限
const staticRoutes = [{path: '/login',name: 'Login',component: LoginView},{path: '/404',name: 'NotFound',component: NotFoundView}
];// 动态路由 - 要根据角色的权限进行显示
export const dynamicRoutes = [{path: '/admin',name: 'admin',component: HomeView,meta: {title: "首页",title_path: '/admin',sub_title: "后台管理",roles: ['admin', 'accountA', 'accountB'] // 修正为数组格式},children: [{path: 'user',name: 'user',component: UserView,meta: {title: "用户管理",title_path: '/admin/user',sub_title: "用户信息编辑",roles: ['admin', 'accountA', 'accountB'] // 修正为数组格式}},{path: 'role',name: 'role',component: RoleView,meta: {title: "角色管理",title_path: '/admin/role',sub_title: "角色信息编辑",roles: ['admin', 'accountA'] // 修正为数组格式}},{path: 'permis',name: 'permis',component: PermissView,meta: {title: "权限管理",title_path: '/admin/permis',sub_title: "权限信息编辑",roles: ['admin'] // 修正为数组格式}}]}
]
2. 路由初始化
const router = createRouter({history: createWebHistory(process.env.BASE_URL),routes: staticRoutes // 初始只加载静态路由
})
3. 动态路由添加
在用户登录后,根据角色动态添加路由:
// 过滤出用户有权限访问的路由
function filterRoutes(routes: RouteRecordRaw[], userRoles: string[]) {return routes.filter(route => {// 如果没有设置roles,则默认允许访问if (!route.meta?.roles) return true// 检查用户是否有任一所需角色return route.meta.roles.some(role => userRoles.includes(role))})
}// 添加动态路由
function addDynamicRoutes(userRoles: string[]) {const accessibleRoutes = filterRoutes(dynamicRoutes, userRoles)// 先移除可能已存在的动态路由router.getRoutes().forEach(route => {if (dynamicRoutes.some(dr => dr.name === route.name)) {router.removeRoute(route.name!)}})// 添加新路由accessibleRoutes.forEach(route => {router.addRoute(route)})
}
4. 路由守卫实现
router.beforeEach((to, from, next) => {const store = useStore()const userRoles = store.state.roles || []// 1. 检查是否需要权限if (to.meta.roles) {const requiredRoles = to.meta.rolesconst hasPermission = requiredRoles.some(role => userRoles.includes(role))if (!hasPermission) {return next('/404') // 无权限跳转404}}// 2. 检查是否已登录但访问登录页if (to.name === 'Login' && store.state.token) {return next('/admin') // 已登录用户跳转首页}next()
})
三、完整工作流程
-
应用初始化:
• 只加载静态路由(登录页、404页)
• 用户访问时首先进入登录页 -
用户登录:
vuex:store/index.ts :
import { createStore } from 'vuex'export default createStore({state: {roles: [],},getters: {getRoles: state => state.roles // 添加一个getter来获取roles},mutations: {SET_ROLES(state, roles) { // 添加mutation来修改rolesstate.roles = roles}},actions: {setRoles({ commit }, roles) { // 正确的action写法commit('SET_ROLES', roles) // 通过commit调用mutation}},modules: {} })view/LoginView.vue :
import { dynamicRoutes } from '@/router'; // 导入动态路由 // 检查当前用户角色的操作---可以放在一个js文件中导入。这里直接写入这个文件 function filterRoutesByRole(routes: any[], userRoles: string[]) {return routes.filter((route) => {// 如果没有设置roles,或者用户角色包含任一所需角色return (!route.meta?.roles ||route.meta.roles.some((role: string) => userRoles.includes(role)));}); } function generateDynamicRoutes() {const userRoles = store.state.roles || [];console.log(userRoles)const accessibleRoutes = filterRoutesByRole(dynamicRoutes, userRoles);// 先移除可能已存在的动态路由router.getRoutes().forEach((r) => {if (dynamicRoutes.some((dr) => dr.name === r.name)) {router.removeRoute(r.name!);}});// 添加新路由accessibleRoutes.forEach((route) => {router.addRoute(route);}); } // 完结...// 登录按钮 const submitForm = async () => {try {// 尝试对表单进行验证,如果验证不通过,则不会执行后续代码await formRef.value?.validate();// 使用 axios 发送 POST 请求到服务器的登录接口// 将用户名和密码作为请求体发送const response = await axios.post("/api/users/login", {username: ruleForm.value.usermobile, // 用户名字段在请求体中password: ruleForm.value.userpwd, // 密码字段在请求体中});// 打印响应对象到控制台console.log(response);// 弹出响应消息提示用户message.info(response.data.msg);// alert(response.data.msg);// 从响应数据中提取 token、用户 ID 和用户名const role_code: string = response.data.data.userInfo.role_code; // 角色的唯一标识// 注意:这里存在vuex中的数据应该是一个数组,方便后续处理 let role_code_arr = ref<string[]>([]);role_code_arr.value.push(role_code);// 将角色的编码存到vuex中store.commit("SET_ROLES", role_code_arr);// 生成动态路由generateDynamicRoutes();} catch (error: any) {// 如果请求失败或验证失败,则捕获错误并打印到控制台console.error("请求失败:", error);message.error(error.response.data.msg);} };导航守卫:router/index.ts :
import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router' // import { useUserStore } from '@/store/user' import { useStore } from "vuex"; // 路由组件导入 const HomeView = () => import('../views/HomeView.vue') const UserView = () => import('../views/UserView.vue') const RoleView = () => import('@/views/RoleView.vue') const PermissView = () => import('@/views/PermissView.vue') const LoginView = () => import('../views/LoginView.vue') const NotFoundView = () => import('../views/NotFound.vue')// 静态路由 const staticRoutes = [{path: '/login',name: 'Login',component: LoginView},{path: '/404',name: 'NotFound',component: NotFoundView} ];// 动态路由 export const dynamicRoutes = [{path: '/admin',name: 'admin',component: HomeView,meta: {title: "首页",title_path: '/admin',sub_title: "后台管理",roles: ['admin', 'accountA', 'accountB'] // 修正为数组格式},children: [{path: 'user',name: 'user',component: UserView,meta: {title: "用户管理",title_path: '/admin/user',sub_title: "用户信息编辑",roles: ['admin', 'accountA', 'accountB'] // 修正为数组格式}},{path: 'role',name: 'role',component: RoleView,meta: {title: "角色管理",title_path: '/admin/role',sub_title: "角色信息编辑",roles: ['admin', 'accountA'] // 修正为数组格式}},{path: 'permis',name: 'permis',component: PermissView,meta: {title: "权限管理",title_path: '/admin/permis',sub_title: "权限信息编辑",roles: ['admin'] // 修正为数组格式}}]} ]const router = createRouter({// history: createWebHistory(import.meta.env.BASE_URL),history: createWebHistory(process.env.BASE_URL),routes:staticRoutes })// 导航守卫 router.beforeEach((to, from, next) => {const store = useStore();const userRoles = to.meta.roles || [];console.log(store.state.roles)// 如果路由需要权限验证if (to.meta.roles) {// const hasPermission = to.meta.roles.some(role => userStore.roles.includes(role));const hasPermission = userRoles.some((role:any) => store.state.roles.includes(role));// const hasPermission = to.meta.roles.includes(store.roles);if (!hasPermission) {return next({ name: 'NotFound' }); // 无权限时跳转到 404 页面}}next(); // 允许访问 });export default router生成动态菜单:HomeView.vue:
import { useStore } from "vuex";
const store = useStore();import { useRouter, useRoute } from "vue-router";
const router = useRouter();
const route = useRoute();// 现生成一个动态菜单--需要从meta中拿到
const all_router = router.getRoutes();
// 把全部的路由meta拿到
const all_meta_data = all_router.map((item) => {return item.meta;
});
// 过滤出isMenu === true的meta
const meta_data = all_meta_data.filter((item) => {return item.isMenu === true;
});
// 从vuex中拿到此用户的角色组
const userRoles = store.state.roles || [];
// 过滤出此角色可以访问的路由meta
const finish_meta = meta_data.filter((item) => {return item.roles.some((role: string) => userRoles.includes(role));// return item.roles.includes(store.state.st)
});
// 最后拿到可以给菜单使用的数组菜单
const iconComponents = { // 图标的命名,由于meta中的icon是字符串,这里也是一种解决方法AppstoreOutlined: AppstoreOutlined,InboxOutlined: InboxOutlined,DesktopOutlined: DesktopOutlined
};
const use_meta = finish_meta.map((item) => {return {key:item.title_path,// icon:item.icon.replace(/^["']|["']$/g, ''),// icon: iconMap[item.icon] || null,icon: iconComponents[item.icon],label:item.title}
});
-
路由导航:
• 每次路由跳转时,路由守卫会检查:
◦ 目标路由是否需要特定权限
◦ 当前用户是否拥有所需权限
• 根据检查结果允许或拒绝访问 -
用户注销:
function logout() {// 清除用户信息store.commit('CLEAR_USER')// 重置路由router.getRoutes().forEach(route => {if (dynamicRoutes.some(dr => dr.name === route.name)) {router.removeRoute(route.name!)}})// 跳转到登录页router.push('/login') }
检查用户角色操作的作用分析
您提供的代码中关于用户角色检查的部分实际上是非常必要的,它在整个权限控制流程中扮演着关键角色。让我详细解释其作用和必要性:
一、角色检查的核心作用
1. 权限过滤的核心机制
function filterRoutesByRole(routes: any[], userRoles: string[]) {return routes.filter((route) => {return (!route.meta?.roles || // 无权限限制的路由直接放行route.meta.roles.some((role: string) => userRoles.includes(role)) // 检查角色匹配);});
}
这段代码实现了:
• 路由筛选:根据用户角色过滤出可访问的路由
• 权限验证:确保用户只能看到自己有权限访问的路由
• 安全控制:防止越权访问敏感路由
2. 动态路由生成流程
二、为什么不能省略?
1. 必要性分析
| 检查环节 | 作用 | 省略后果 |
|---|---|---|
| 角色存储 | 保留用户权限标识 | 无法识别用户权限级别 |
| 路由过滤 | 生成个性化路由表 | 所有用户看到相同菜单 |
| 权限验证 | 防止越权访问 | 安全漏洞风险 |
2. 实际应用场景
假设:
• 用户角色:['editor']
• 路由配置:
[{ path: '/admin', meta: { roles: ['admin'] }},{ path: '/editor', meta: { roles: ['editor'] }}
]
无过滤时:用户可以看到/admin路由但无法正常使用,导致错误
有过滤时:用户只能看到/editor路由,体验更合理
三、代码优化建议
1. 类型安全改进
// 在类型声明文件中
declare module 'vue-router' {interface RouteMeta {roles?: string[];// 其他元字段...}
}// 过滤函数改进
function filterAccessibleRoutes(routes: RouteRecordRaw[], userRoles: string[]): RouteRecordRaw[] {return routes.filter(route => {const requiredRoles = route.meta?.roles || []return requiredRoles.length === 0 || requiredRoles.some(role => userRoles.includes(role))})
}
2. 性能优化
// 避免重复计算
const userRoles = computed(() => store.state.roles)// 路由添加前检查
function needsRefresh(newRoutes: RouteRecordRaw[]) {const currentRoutes = router.getRoutes()return (newRoutes.length !== currentRoutes.length ||newRoutes.some(route => !currentRoutes.some(r => r.path === route.path)))
}
3. 错误处理增强
function generateDynamicRoutes() {try {const userRoles = store.state.roles || []if (!Array.isArray(userRoles)) {throw new Error('角色数据格式错误')}const accessibleRoutes = filterRoutesByRole(dynamicRoutes, userRoles)// 清除旧路由逻辑...// 添加新路由逻辑...} catch (err) {console.error('路由生成失败:', err)router.push('/error?code=route_init_failed')}
}
四、完整工作流程
-
用户登录
• 获取角色信息 → 存储到Vuex -
路由生成
-
访问控制
• 路由守卫二次验证
• 菜单动态生成
五、总结
您代码中的角色检查操作:
• ✅ 不是多余的:是权限系统的核心逻辑
• ✅ 必不可少:确保路由与权限的精确匹配
• ✅ 可以优化:类型、性能、错误处理等方面
建议保留这部分逻辑,同时参考上述优化建议进行改进,可以使您的权限控制系统更加健壮和安全。
四、最佳实践方案
4.1 路由配置规范
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| path | string | 是 | 路由路径 |
| component | Component | 是 | 组件引用 |
| meta.roles | string[] | 否 | 允许的角色 |
| meta.title | string | 推荐 | 页面标题 |
| meta.icon | string | 可选 | 菜单图标 |
| meta.cache | boolean | 否 | 是否缓存 |
4.2 权限检查方案对比
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 前端控制 | 响应快,体验好 | 安全性较低 | 内部管理系统 |
| 前后端结合 | 安全性高 | 实现复杂 | 高安全要求系统 |
| 动态接口 | 灵活度高 | 性能开销大 | 权限频繁变更系统 |
4.3 性能优化建议
-
路由懒加载
component: () => import('@/views/HeavyPage.vue') -
路由分组打包
// vite.config.js rollupOptions: {output: {manualChunks: {admin: ['@/views/Admin*.vue']}} } -
持久化缓存
// 使用pinia-plugin-persistedstate persist: {paths: ['user.roles'] }
五、常见问题解决方案
5.1 问题排查表
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 路由跳转循环 | 守卫逻辑错误 | 检查重定向条件 |
| 菜单不更新 | 路由未正确重置 | 确保先remove后add |
| 404错误 | 路由未加载 | 检查addRoute调用 |
| 权限失效 | 角色信息丢失 | 检查状态持久化 |
5.2 典型错误处理
// 安全的路由添加方式
function safeAddRoute(route) {try {if (router.hasRoute(route.name)) {router.removeRoute(route.name)}router.addRoute(route)return true} catch (err) {console.error('路由添加失败:', err)return false}
}
六、完整示例项目结构
/src
├── router
│ ├── index.ts # 路由入口
│ ├── static.ts # 静态路由
│ └── dynamic.ts # 动态路由配置
├── stores
│ └── auth.ts # 权限状态管理
├── utils
│ └── permission.ts # 权限验证工具
└── views├── public # 公共页面└── admin # 权限页面
通过这套系统化方案,开发者可以快速实现:
- 基于角色的精细化权限控制
- 动态菜单的自动生成
- 安全的访问验证机制
- 良好的用户体验和性能表现
相关文章:
Vue3 路由权限管理:基于角色的路由生成与访问控制
Vue3 路由权限管理:基于角色的路由生成与访问控制 一、核心概念 1.1 大致流程思路: 用户在登录完成的时候,后端给出一个此登录用户对应的角色名字,此时可以将这个用户的角色存起来(vuex/pinia)中,在设置路由时的met…...
LLM Agents的历史、现状与未来趋势
引言 大型语言模型(Large Language Model, LLM)近年在人工智能领域掀起革命,它们具备了出色的语言理解与生成能力。然而,单纯的LLM更像是被动的“回答者”,只能根据输入给出回复。为了让LLM真正“行动”起来ÿ…...
忘记mysql的root用户密码(已解决)
1、打开数据库可视化界面(比如MySQL workbench) 2、执行select host,user,authentication_string from mysql.user; 3、把‘authentication_string’下面的字段 复制到MD5在线解密网页中(比如md5在线解密)...
【Pandas】pandas DataFrame set_flags
Pandas2.2 DataFrame Attributes and underlying data 方法描述DataFrame.index用于获取 DataFrame 的行索引DataFrame.columns用于获取 DataFrame 的列标签DataFrame.dtypes用于获取 DataFrame 中每一列的数据类型DataFrame.info([verbose, buf, max_cols, …])用于提供 Dat…...
Vue3.2 项目打包成 Electron 桌面应用
本文将详细介绍如何将基于 Vue3.2 的项目打包成 Electron 桌面应用。通过结合 Electron 和 Vue CLI 工具链,可以轻松实现跨平台桌面应用的开发与发布。 1. 项目结构说明 项目主要分为以下几个部分: electron/main.js:Electron 主进程文件。…...
git stash pop 后反悔操作
当使用 git stash pop 应用并删除某个存储(stash)后,如果想撤销该操作(即恢复工作目录到 pop 前的状态,并重新将存储放回存储栈),可以按以下步骤操作: 1 强制丢弃所有未提交的更改&…...
Spring Boot 集成 MongoDB 时自动创建的核心 Bean 的详细说明及表格总结
以下是 Spring Boot 集成 MongoDB 时自动创建的核心 Bean 的详细说明及表格总结: 核心 Bean 列表及详细说明 1. MongoClient 类型:com.mongodb.client.MongoClient作用: MongoDB 客户端核心接口,负责与 MongoDB 服务器建立连接、…...
TypeScript面试题集合【初级、中级、高级】
初级面试题 什么是TypeScript? TypeScript是JavaScript的超集,由Microsoft开发,它添加了可选的静态类型和基于类的面向对象编程。TypeScript旨在解决JavaScript的某些局限性,比如缺乏静态类型和基于类的面向对象编程,…...
ubuntu 20.04 编译和运行SC-LeGo-LOAM
1.搭建文件目录和clone代码 mkdir -p SC-LeGo-LOAM/src cd SC-LeGo-LOAM/src git clone https://github.com/AbangLZU/SC-LeGO-LOAM.git cd .. 2.修改代码 需要注意的是原作者使用的是Ouster OS-64雷达,需要更改utility.h文件中适配自己的雷达类型,而…...
CentOS 7安装hyperscan
0x00 前言 HyperScan是一款由Intel开发的高性能正则表达式匹配库,专为需要快速处理大量数据流的应用场景而设计。它支持多平台运行,包括Linux、Windows和macOS等操作系统,并针对x86架构进行了优化,以提供卓越的性能表现。HyperSc…...
Quartz MisFire补偿机制 任务补偿 任务延迟 错过触发策略
介绍 在 Quartz 中,MisFire(错过触发)是指触发器错过了预定的触发时间,通常是由于系统延迟、任务执行时间过长或者调度器本身未能及时执行任务等原因。这种情况可能会导致任务无法按预期的时间执行。为了应对这些问题,…...
AI训练存储架构革命:存储选型白皮书与万卡集群实战解析
一、引言 在人工智能技术持续高速发展的当下,AI 训练任务对存储系统的依赖愈发关键,而存储系统的选型也变得更为复杂。不同的 AI 训练场景,如机器学习与大模型训练,在模型特性、GPU 使用数量以及数据量带宽等方面的差异ÿ…...
谢志辉和他的《韵之队诗集》:探寻生活与梦想交织的诗意世界
大家好,我是谢志辉,一个扎根在文字世界,默默耕耘的写作者。写作于我而言,早已不是简单的爱好,而是生命中不可或缺的一部分。无数个寂静的夜晚,当世界陷入沉睡,我独自坐在书桌前,伴着…...
UE5 Simulation Stage
首先将Grid2D创建出来,然后设置值,Grid2D类似于在Niagara系统中的RenderTarget2D,可以进行绘制,那么设置大小为512 * 512 开启Niagara粒子中的Simulation Stage 然后开始编写我们的自定义模块 模块很简单,TS就是Textur…...
Swift 解 LeetCode 250:搞懂同值子树,用递归写出权限系统检查器
文章目录 前言问题描述简单说:痛点分析:到底难在哪?1. 子树的概念搞不清楚2. 要不要“递归”?递归从哪开始?3. 怎么“边遍历边判断”?这套路不熟 后序遍历 全局计数器遍历过程解释一下:和实际场…...
怎样使用Python编写的Telegram聊天机器人
怎样使用Python编写的Telegram聊天机器人 代码直接运行可用 以下是对这段代码的详细解释: 1. 导入必要的库 import loggingfrom telegram import Update from telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler, filters, MessageHandler import log…...
Elixir语言的移动应用安全
Elixir语言的移动应用安全解析 引言 在当今的数字化时代,移动应用已经成为我们日常生活中不可或缺的一部分。从购物、社交到在线银行,几乎每一个生活领域都与移动应用紧密相连。然而,随着应用的普及,安全问题也随之而来。如何确…...
动态估算gas和gasPrice
目录 一、什么是动态估算? 二、动态估算 Gas(代码示例) ✅ 使用 Ethers.js 估算 gasLimit: 💡 发送交易时加一点 buffer: 三、动态估算 gasPrice / maxFee ✅ 获取当前 baseFee(用 provider): ✅ 搭配交易一起发送: 四、完整组合:动态估算 Gas + EIP-1559 费用…...
数据清洗
map阶段:按行读入内容,对内容进行检查,如果字段的个数少于等于11,就删除这条日志(不保留)去除日志中字段个数小于等于11的日志内容。 <偏移量,第一行的内容> → <通过刷选之后的第一行…...
增益调度控制 —— 理论、案例与交互式 GUI 实现
目录 增益调度控制 —— 理论、案例与交互式 GUI 实现一、引言二、增益调度控制的基本原理三、数学模型与公式推导四、增益调度控制的优势与局限4.1 优势4.2 局限五、典型案例分析5.1 案例一:航空飞行控制中的增益调度5.2 案例二:发动机推力控制中的增益调度5.3 案例三:化工…...
关于OEC/OEC-turbo刷机问题的一些解决方法(2)——可能是终极解决方法了
前面写了两篇关于OEC/OEC-turbo刷机问题的文章了,从刷机过程、刷机中遇到的问题,以及遇到最多但始终无法有效解决的下载boot失败的问题的剖析,最近确实也做了一些工作,虽然没有最终解决,但也算是这系列文章里面阶段性的…...
前后端接口参数详解与 Mock 配置指南【大模型总结】
前后端接口参数详解与 Mock 配置指南 一、前端请求参数类型及 Mock 处理 1.1 URL 路径参数 (Path Parameters) 场景示例: GET /api/users/{userId}/orders/{orderId}Mock.js 处理: Mock.mock(/\/api\/users\/(\d)\/orders\/(\d)/, get, (options) &g…...
瓦片数据合并方法
影像数据 假如有两份影像数据 1.全球底层影像0-5级别如下: 2.局部高清影像数据级别9-14如下: 合并方法 将9-14文件夹复制到全球底层0-5的目录下 如下: 然后合并xml文件 使得Tileset设置到最高级(包含所有级别)&…...
第16届蓝桥杯单片机模拟试题Ⅰ
试题 代码 sys.h #ifndef __SYS_H__ #define __SYS_H__#include <STC15F2K60S2.H> //onewire.c float getT(); //sys.c extern unsigned char UI; extern bit touch_mode; extern float jiaozhun; extern float canshu; extern float temper; void init74hc138(unsigned…...
mac 卸载流氓软件安全助手
之前个人电脑在公司使用过一段时间,为了使用网线联网安装了公司指定的 联软上网助手,谁知安装容易卸载难,后来找运维来卸载,输入管理员密码后,也无反应,最后不了了之了,这个毒瘤软件长期在后台驻…...
EM算法到底是什么东东
EM(Expectation-Maximization期望最大化)算法是机器学习中非常重要的一类算法,广泛应用于聚类、缺失数据建模、隐变量模型学习等场景,比如高斯混合模型(GMM)就是经典应用。 🐤 第一步ÿ…...
⭐算法OJ⭐滑动窗口最大值【双端队列(deque)】Sliding Window Maximum
文章目录 双端队列(deque)详解基本特性常用操作1. 构造和初始化2. 元素访问3. 修改操作4. 容量操作 性能特点时间复杂度:空间复杂度: 滑动窗口最大值题目描述方法思路解决代码 双端队列(deque)详解 双端队列(deque,全称double-ended queue)是…...
oracle 快速创建表结构
在 Oracle 中快速创建表结构(仅复制表结构,不复制数据)可以通过以下方法实现,适用于需要快速复制表定义或生成空表的场景 1. 使用 CREATE TABLE AS SELECT (CTAS) 方法 -- 复制源表的全部列和数据类型,但不复制数据 C…...
沧州铁狮子
又名“镇海吼”,是中国现存年代最久、形体最大的铸铁狮子,具有深厚的历史文化底蕴和独特的艺术价值。以下是关于沧州铁狮子的详细介绍: 历史背景 • 铸造年代:沧州铁狮子铸造于后周广顺三年(953年)&#…...
Python•判断循环
ʕ⸝⸝⸝˙Ⱉ˙ʔ ♡ 判断🍰常用的判断符号(比较运算符)andor括号notin 和 not inif-elif-else循环🍭计数循环 forrange()函数简易倒计时enumerate()函数zip()函数遍历列表遍历元组遍历字符串遍历字典条件循环 while提前跳转 continue跳出循环 break能量站😚判断🍰 …...
