Skip to content

控制

我们通过多种方式来控制用户的权限,可以精准的针对不同的用户来达到想要的效果。

首先从权限维度来说,主要分为两方面: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 属性对象上。

例:

页面上有两个按钮:新增和删除

新增和删除按钮.png

现在 requestData 对象下面的 code 对象是一个空对象

code空对象.png

正常情况下,页面中的该 code 值应该是从接口返回的,或者根据其他配置进行设置的,现在为了方便,我们直接修改它的值

code设置新增和删除.png

然后我们给新增和删除按钮分别配置上不同的 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
  }]
}]

上面展示的是数据视图的代码形式,我们在设计的时候直接通过属性配置的方式进行设置即可

配置control.png

这时新增按钮通过 add 标识来控制,删除按钮通过 delete 标识来控制,现在我们去掉删除按钮的权限

只有新增code.png

那么页面上就没有了删除按钮

只有新增按钮.png

requestData.code 对象除了可以设置权限标识为 truefalse 之外,还能够设置为权限对象

比如可以设置成这样

设置为权限对象.png

我们设置了一个 pageButton 的权限对象,里面包含了 adddelete 的控制

然后修改一下这两个按钮的 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
  }]
}]

这样页面上就只剩删除按钮了

只有删除按钮.png

对象的层级没有限制,也就是说可以任意的制定权限控制的规则和分类等。比如 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 赋值上相应的身份标识

identity赋值.png

当前用户具有 roleAroleBroleC 三个身份,因此两个按钮都能够渲染出来

新增和删除按钮.png

当我们去掉 roleAroleB 两个身份时

只有roleC身份.png

相应的按钮权限也会实时生效

只有新增按钮.png

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 身份没有新增按钮的权限

只有删除按钮.png

if

如果需要手动的去做判断,那么可以使用 if 字段,它的值是一个函数。

可以在函数内部执行某些逻辑,函数体内可以通过this获取到暴露出来的属性和方法等。

if能获取的变量.png

然后手动指定返回值为 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 的组件

只有新增按钮.png

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
  }]
}]

这样就可以做到在组件渲染完成之后进行任意的处理

通过call处理.png

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 对象中

dom引用.png

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 对象中

view引用.png

可以看到除了dom和view的引用被添加到了 controlData 对象中外,还有一个以DT结尾的对象引用也被添加到了 controlData 对象中。

dom和view需要手动指定后才会被收集到 controlData 对象中,所有被命名的数据视图都会自动的被收集到 controlData 对象中,并以DT结尾来标识

提示:

codepermissionnoPermissionif 可以同时存在,但是他们之间有一个优先级的关系,因此设置的时候尽量不要冲突,如 permission 设定为 [roleA]noPermission 也设定为 [roleA],那么 noPermission 将不会生效。

他们之间的优先级关系为: code > permission > noPermission > if,当设定产生冲突时,将会按照这个优先级进行处理。

注意 permissionnoPermission 必须要设定为数组的形式,不支持字符串的设定。

domview 字段都是字符串,他们不做任何逻辑处理,只是保留了元素和视图的引用,以备在其他地方引用。