权限控制(vue)
权限控制(vue)
经常会遇到,角色权限控制问题,若是页面控制,倒好说,可如果是当前页面部分可见不可见,这就有些麻烦,如果加上条件就更加苛刻。之前只是简单的v-if
进行控制,如今想试试指令(网上一直有这些操作方式)
参考
应用场景
- 权限控制
- dom隐藏(不推荐)
- 直接从dom节点删除
- 依据传入的数据动态进行修改
代码
需求:需要实现一个依据动态参数进行修改的模块
test.vue
template
<div class="test-height">
<!-- 指令调用,status是动态参数 -->
<h1 v-permission="{ role: ['so'], status }">test</h1>
</div>
js
import permission from '@/directives/permission'
export default {
...
directives: { permission },
data () {
return {
status: false
}
},
mounted () {
// 动态修改参数
setTimeout(() => {
this.status = !this.status
}, 1000)
}
}
permission.js
import store from '@/store'
const permission = (el, binding, vnode, oldVnode) => {
const { value, oldValue } = binding
if (!value || (value.role && !Array.isArray(value.role))) {
throw new Error(`need roles! Like v-permission="{ role: ['admin','editor'], [status 可传 boolean]}"`)
}
// 绑定的参数
const status = value.hasOwnProperty('status') ? value.status : false
const roles = store.getters && store.getters.roles
const permissionRoles = value.role || [] const hasPermission = roles.some(role => {
return permissionRoles.includes(role)
}) if (!hasPermission || (hasPermission && status)) {
/**
* TODO:
* 1. 给父元素添加唯一id
* 2. 同时找到子元素当前父元素的第几个位置
*/
const rid = getRandomId()
const index = getChildInParentPosition(el)
el.parentNode.setAttribute('id', rid)
el.dataset.id = rid
el.dataset.index = index
el.parentNode && el.parentNode.removeChild(el)
}
// 判断条件
if (oldValue && oldValue && oldValue.status === true && value.status === false) {
// 此处会在 update时触发
const { index, id } = el.dataset
const parent = document.getElementById(id)
// 根据index找到需要插入父节点的位置
parent.insertBefore(el, Array.from(parent.children)[index])
}
}
export default {
// 此处父元素存在
inserted: permission,
// 此处数据更新
update: permission
}
- 随机生成id
function getRandomId () {
var randomId = 'yxyxyxxyxyy'.replace(/[xy]/g, function (item) {
var n = Math.random() * 12 | 0
var v = item === 'x' ? n : (n & 0x3 | 0x8)
v = item === 'y' ? 'abcdefghijklmnopqrstuvwsyz'.substr(Math.random() * 26 | 0, 1) : v
return v.toString(16)
})
return randomId
}
- 找到子节点在父节点中的位置
function getChildInParentPosition (node) {
// 用来保留子元素 【cloneNode(true) 深度克隆】
const Parent = node.parentNode.cloneNode(true)
let key = -1
Array.from(Parent.children).filter((item, index) => {
// 判断子节点是否相同 【isEqualNode】
if (item.isEqualNode(node)) {
key = index
}
})
return key
}
- 随机生成id
效果图
默认不显示,数据回来显示
- 单个元素
多个元素
默认显示,数据回来不显示
单个元素
多个元素
总结
- 虽然可以解决基本需求,但是还是有问题,若是兄弟元素都有权限控制,恐怕回显时,会错位
- 因而推荐还是使用
v-if
- 上述方式,只能是应付简单的,复杂的依旧有些吃力
- 在指令执行时,提前拿到父节点和子节点的对应关系,然后在
update
时,进行全局获取,因而生成的id
必须唯一 - 若是想使用,适用于其他场景,需要给需要权限控制的添加一个父元素,同时保证子元素唯一即可
知识点
cloneNode(true)
使用深度克隆是由于父元素因为实时变化才是用的,可以保留子节点isEqualNode
用来判断两个子节点是否相同(长知识了)update
时,需要将节点添加到父节点上,此时vnode, oldVnode
的parent
都没有值
权限控制(vue)的更多相关文章
- Spring Cloud实战 | 第十一篇:Spring Cloud Gateway 网关实现对RESTful接口权限控制和按钮权限控制
一. 前言 hi,大家好,这应该是农历年前的关于开源项目 的最后一篇文章了. 有来商城 是基于 Spring Cloud OAuth2 + Spring Cloud Gateway + JWT实现的统 ...
- 基于Vue实现后台系统权限控制
原文地址:http://refined-x.com/2017/08/29/基于Vue实现后台系统权限控制/,转载请注明出处. 用Vue/React这类双向绑定框架做后台系统再适合不过,后台系统相比普通 ...
- Vue + Element UI 实现权限管理系统 前端篇(十三):页面权限控制
权限控制方案 既然是后台权限管理系统,当然少不了权限控制啦,至于权限控制,前端方面当然就是对页面资源的访问和操作控制啦. 前端资源权限主要又分为两个部分,即导航菜单的查看权限和页面增删改操作按钮的操作 ...
- vue项目权限控制
Vue权限控制有各种方法,大概分为两个方向: 把当前角色对应的权限保存在浏览器本地(容易被恶意修改): 将操作权限保存在vuex中(推荐此种方式:页面一刷新就没了,可以再次向后端请求相关数据,始终保持 ...
- vue实现菜单权限控制
大家在做后台管理系统时一般都会涉及到菜单的权限控制问题.当然解决问题的方法无非两种——前端控制和后端控制.我们公司这边的产品迭代速度较快,所以我们是从前端控制路由迭代到后端控制路由.下面我会分别介绍这 ...
- vue中如何实现后台管理系统的权限控制
vuejs单页应用的权限管理实践 一.前言 在广告机项目中,角色的权限管理是卡了挺久的一个难点.首先我们确定的权限控制分为两大部分,其中根据粒的大小分的更细: 接口访问的权限控制 页面的权限控制 菜单 ...
- pc vue 项目中的菜单权限控制
在pc 管理系统这种类型的产品,通常会涉及到账号权限的控制,不同的账号权限能浏览的功能模块是不同的,对应侧边栏菜单模块的显示也会不同. 场景一.(电商类管理系统) 登录 登录后,依次获取账号 toke ...
- vue基于页面中按钮权限控制
main.js // 权限 /** 权限指令,对按钮权限的控制 **/ Vue.directive('allow', { bind: function(el, binding) { // 通过当前按钮 ...
- Vue 动态路由的实现以及 Springsecurity 按钮级别的权限控制
思路: 动态路由实现:在导航守卫中判断用户是否有用户信息,通过调用接口,拿到后台根据用户角色生成的菜单树,格式化菜单树结构信息并递归生成层级路由表并使用Vuex保存,通过 router.addRout ...
随机推荐
- linux-ntp-10
Unix/linux类:ntp.aliyun.com,ntp1-7.aliyun.com windows类: time.pool.aliyun.com s1a.time.edu.cn 北京邮电大学 s ...
- html body标签 语法
html body标签 语法 标签body是什么意思? 标签body是一个网页的身体部分,也就是用于定义网页的主体内容,也是一个HTML文档中必须的部分. 作用:定义文档的主体. 广州大理石机械构件 ...
- Java+超大文件上传
之前仿造uploadify写了一个HTML5版的文件上传插件,没看过的朋友可以点此先看一下~得到了不少朋友的好评,我自己也用在了项目中,不论是用户头像上传,还是各种媒体文件的上传,以及各种个性的业务需 ...
- codevs 1002 搭桥x
题目描述 Description 有一矩形区域的城市中建筑了若干建筑物,如果某两个单元格有一个点相联系,则它们属于同一座建筑物.现在想在这些建筑物之间搭建一些桥梁,其中桥梁只能沿着矩形的方格的边沿搭建 ...
- sh_07_火车站安检
sh_07_火车站安检 # 定义布尔型变量 has_ticket 表示是否有车票 has_ticket = True # 定义整型变量 knife_length 表示刀的长度,单位:厘米 knife_ ...
- Vue项目开发,nprogress进度条加载之超详细讲解及实战案例
Nprogress的默认进度条很细,它的设计灵感主要来源于 谷歌,YouTube 他的安装方式也很简单,你可以有两种使用方式: 直接引入js和css文件 使用npm安装的的方式 直接引入: Npm安装 ...
- Jedis下的ShardedJedis
jedis客户端操作redis主要三种模式:单台模式.分片模式(ShardedJedis).集群模式(BinaryJedisCluster) ShardedJedis是通过一致性哈希来实现分布式缓存的 ...
- BZOJ 3143 Luogu P3232 [HNOI2013]游走 (DP、高斯消元)
题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=3143 (luogu) https://www.luogu.org/pro ...
- java复制项目中的补丁,完整的包路径
package com.bytter.audit.iface.util; import java.io.BufferedInputStream; import java.io.BufferedOutp ...
- 一款基于jQuery的分页插件
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...