Appearance
控制
我们通过多种方式来控制用户的权限,可以精准的针对不同的用户来达到想要的效果。
首先从权限维度来说,主要分为两方面:1. 用户拥有的角色,2. 动态配置的code
再从控制的手段来说,也主要分为两方面:1. 操作视图,2. 操作dom元素
由于有交叉部分,并且还有很多细化的地方,因此我们按照实现方式来对此进行说明。
对于权限的控制,我们可以通过在组件的json对象上添加 control 属性对象来实现。
每个组件都可以配置 control 属性,其中的 if 属性是个方法,通过返回值的 true 和 false 来控制组件的显示及隐藏。
比如在按钮组件上添加权限控制:
js
[{
col: [{
_span: 24,
default: [{
is:'lc-button',
default: [{
is: 'lc-text',
default: '新增'
}],
control: {
code: 'add',
permission: ['roleA', 'roleC'],
noPermission: ['roleM'],
if: function() {
//控制组件是否渲染
return true
},
call: function() {
//组件渲染完毕,可以执行操作
console.log('组件渲染完毕,可以执行操作')
},
dom: 'button_add',
view: 'button_add'
},
}]
}]
}]code
我们在访问不同的页面的时候,可能会根据配置的不同,以及接口返回的数据不同,把得到的一个或多个 code 值存储起来,每个页面都可能是不一样的 code 组,当解析该组件的时候,会根据当前设定的 code 去对应的 code 组里面去查找,如果找到则进行渲染,如果找不到,则直接跳过该组件。
存储 code 的集合在 requestData 对象的 code 属性对象上。
例:
页面上有两个按钮:新增和删除
现在 requestData 对象下面的 code 对象是一个空对象
正常情况下,页面中的该 code 值应该是从接口返回的,或者根据其他配置进行设置的,现在为了方便,我们直接修改它的值
然后我们给新增和删除按钮分别配置上不同的 code
js
[{
col: [{
default: [{
is: 'lc-button',
control: {
code: 'add'
},
default: [{
is: 'lc-text',
default: '新增'
}]
}, {
is: 'lc-button',
_type: 'danger',
control: {
code: 'delete'
},
default: [{
is: 'lc-text',
default: '删除'
}]
}],
_span: 24
}]
}]上面展示的是数据视图的代码形式,我们在设计的时候直接通过属性配置的方式进行设置即可

这时新增按钮通过 add 标识来控制,删除按钮通过 delete 标识来控制,现在我们去掉删除按钮的权限
那么页面上就没有了删除按钮
requestData.code 对象除了可以设置权限标识为 true 或 false 之外,还能够设置为权限对象
比如可以设置成这样
我们设置了一个 pageButton 的权限对象,里面包含了 add 和 delete 的控制
然后修改一下这两个按钮的 control 配置
js
[{
col: [{
default: [{
is: 'lc-button',
control: {
code: 'pageButton.add'
},
default: [{
is: 'lc-text',
default: '新增'
}]
}, {
is: 'lc-button',
control: {
code: 'pageButton.delete'
},
_type: 'danger',
default: [{
is: 'lc-text',
default: '删除'
}]
}],
_span: 24
}]
}]这样页面上就只剩删除按钮了
对象的层级没有限制,也就是说可以任意的制定权限控制的规则和分类等。比如 pageButton.add.enable,只要属性值为逻辑true即可
permission
用户在登录成功之后,会获取到配置的对应身份组 identity,我们可以为 permission 字段设定具有一个或多个值的权限组,
如果 permission 中的至少一个字段能够在 identity 中找到,那么就会进行渲染,否则直接跳过该组件。
还是使用上面的例子,这次我们用 permission 字段来控制按钮的权限
js
[{
col: [{
default: [{
is: 'lc-button',
control: {
permission: ['roleA', 'roleC']
},
default: [{
is: 'lc-text',
default: '新增'
}]
}, {
is: 'lc-button',
_type: 'danger',
control: {
permission: ['roleB']
},
default: [{
is: 'lc-text',
default: '删除'
}]
}],
_span: 24
}]
}]然后给我们的 identity 赋值上相应的身份标识

当前用户具有 roleA、roleB、roleC 三个身份,因此两个按钮都能够渲染出来
当我们去掉 roleA、roleB 两个身份时

相应的按钮权限也会实时生效
noPermission
我们可以为 noPermission 字段设定具有一个或多个值的无权限组,如果 noPermission 中的至少一个字段能够在身份组 identity 中找到,那么就表示该角色无权渲染该组件,将会直接跳过,否则一个都未找到的话,那么才会进行渲染。
同样,我们将上面配置的 permission 改为 noPermission
js
[{
col: [{
default: [{
is: 'lc-button',
control: {
noPermission: ['roleA', 'roleC']
},
default: [{
is: 'lc-text',
default: '新增'
}]
}, {
is: 'lc-button',
_type: 'danger',
control: {
noPermission: ['roleB']
},
default: [{
is: 'lc-text',
default: '删除'
}]
}],
_span: 24
}]
}]这时用户只有 roleC 这一个身份,那么将只会渲染删除按钮,因为 roleC 身份没有新增按钮的权限
if
如果需要手动的去做判断,那么可以使用 if 字段,它的值是一个函数。
可以在函数内部执行某些逻辑,函数体内可以通过this获取到暴露出来的属性和方法等。
然后手动指定返回值为 true 或者 false
如果 if 返回为 false,将会跳过该数据视图的渲染,如果返回为true,那么表示有权限,则会进行渲染。
js
[{
col: [{
default: [{
is: 'lc-button',
control: {
if: function() {
// 这里是一些逻辑
return true
}
},
default: [{
is: 'lc-text',
default: '新增'
}]
}, {
is: 'lc-button',
_type: 'danger',
control: {
if: function() {
// 这里是一些逻辑
return false
}
},
default: [{
is: 'lc-text',
default: '删除'
}]
}],
_span: 24
}]
}]此时只会渲染返回值为 true 的组件
call
当数据视图渲染完成之后,将会调用 call 对应的函数。同样在 call 的函数体内可以通过 this 获取到相应的变量和方法,并可额外通过$el获取到渲染完成的页面中对应的元素,可以进行一些处理操作,不需要返回值。
比如我们通过 describe 对象给新增按钮换一个类型,然后通过 $el 给删除按钮修改一下字体的大小
js
[{
col: [{
default: [{
is: 'lc-button',
control: {
call: function() {
// 这里是一些逻辑
this.describe._type = 'primary'
}
},
default: [{
is: 'lc-text',
default: '新增'
}]
}, {
is: 'lc-button',
_type: 'danger',
control: {
call: function() {
// 这里是一些逻辑
let el = this.$el.ref
el.style.fontSize = '18px'
}
},
default: [{
is: 'lc-text',
default: '删除'
}]
}],
_span: 24
}]
}]这样就可以做到在组件渲染完成之后进行任意的处理
dom
根据设定的 dom 字段的值,当元素渲染完成后,可以通过 controlData 对象来访问对应的元素,如设定为 button_add,那么访问形式就可以这样写:controlData.button_addDom,就得到了对页面元素的引用。
js
[{
col: [{
default: [{
is: 'lc-button',
control: {
dom: 'button_add'
},
default: [{
is: 'lc-text',
default: '新增'
}]
}, {
is: 'lc-button',
_type: 'danger',
control: {
dom: 'button_delete'
},
default: [{
is: 'lc-text',
default: '删除'
}]
}],
_span: 24
}]
}]新增和删除按钮的dom引用就被添加到了 controlData 对象中
view
根据设定的 view 字段的值,当元素渲染完成后,可以通过 controlData 对象来访问对应的视图,如设定为 button_add,那么访问形式就可以这样写:controlData.button_addView,就得到了对该视图的引用。
js
[{
col: [{
default: [{
is: 'lc-button',
control: {
view: 'button_add'
},
default: [{
is: 'lc-text',
default: '新增'
}]
}, {
is: 'lc-button',
_type: 'danger',
control: {
view: 'button_delete'
},
default: [{
is: 'lc-text',
default: '删除'
}]
}],
_span: 24
}]
}]新增和删除按钮的视图引用就被添加到了 controlData 对象中
可以看到除了dom和view的引用被添加到了 controlData 对象中外,还有一个以DT结尾的对象引用也被添加到了 controlData 对象中。
dom和view需要手动指定后才会被收集到 controlData 对象中,所有被命名的数据视图都会自动的被收集到 controlData 对象中,并以DT结尾来标识
提示:
code、permission、noPermission、if可以同时存在,但是他们之间有一个优先级的关系,因此设置的时候尽量不要冲突,如permission设定为[roleA],noPermission也设定为[roleA],那么noPermission将不会生效。他们之间的优先级关系为:
code > permission > noPermission > if,当设定产生冲突时,将会按照这个优先级进行处理。
注意 permission、noPermission 必须要设定为数组的形式,不支持字符串的设定。
dom 和 view 字段都是字符串,他们不做任何逻辑处理,只是保留了元素和视图的引用,以备在其他地方引用。