插槽实现权限控制的核心是将“是否渲染”交由组件内部逻辑判断,而非父组件手动加v-if;组件接收权限标识,结合状态决定插槽内容是否显示,未授权时内容不渲染、不占位、不执行、不触发副作用。

插槽实现权限控制的核心是把“是否渲染”这件事交给组件内部逻辑判断,而不是让父组件手动加 v-if。组件通过接收权限标识(如角色、权限码、权限数组),结合自身状态决定插槽内容是否显示——未授权时,插槽内容自然不渲染,不占位、不执行、不触发副作用。
用具名插槽 + 计算属性控制显隐
适合中等复杂度场景,比如按钮、操作栏、敏感字段等需要按权限动态出现/消失的区域。
- 在权限组件中定义具名插槽(如
v-slot:admin-action),并用v-if绑定计算属性 - 计算属性
hasPermission判断当前用户是否拥有指定权限,支持字符串或数组传入 - 管理员角色可直接返回
true;普通用户则校验权限列表是否包含目标权限码 - 父组件调用时无需写
v-if,只管注入内容:<template><button>删除</button></template>
用作用域插槽暴露权限上下文
当父组件需要根据权限做更细粒度控制(比如部分禁用、文字变灰、tooltip提示无权)时,作用域插槽更合适。
- 子组件通过
<slot :can-edit="userPermissions.includes('sys:user:edit')" :can-delete="..."></slot>向外透出多个布尔状态 - 父组件在作用域插槽内使用解构语法:
<template canedit candelete></template> - 可自由组合:按钮
:disabled="!canEdit"、文字v-if="canDelete"、图标v-show="canEdit" - 避免重复调用权限判断逻辑,所有判定由子组件统一完成并缓存
结合指令封装,兼顾模板与逻辑复用
对已有组件(如 el-button、el-input)快速加权限,不改源码也能生效。
- 自定义指令
v-has-permission="'sys:user:list'",在mounted阶段读取权限并控制el.style.display = 'none' - 配合插槽使用:把带指令的元素包进插槽里,既保持结构清晰,又复用指令逻辑
- 指令中可监听
permissionprop 变化,支持动态权限更新(如切换角色后实时刷新) - 注意:指令仅控制显隐,不销毁组件实例;如需彻底卸载,仍推荐用插槽 +
v-if
防误触与体验优化细节
权限隐藏不是简单删 DOM,还要考虑交互一致性与可访问性。
- 隐藏时保留占位或添加过渡效果(如
opacity: 0; height: 0;),避免页面跳动 - 键盘导航下,被隐藏的插槽内容不应获得焦点;可用
tabindex="-1"或移除focusable属性 - 服务端返回权限数据前,插槽可设默认加载态(如
<slot><span class="loading"></span></slot>) - 开发环境开启权限调试模式:在控制台打印当前匹配的权限项和判定结果,方便排查漏配

















