I have always been interested in the permission design. When I was writing back-end code, I did the permission design, which was quite interesting, but I knew about the front-end button level permission design, but I haven’t implemented it in detail. Recently, THE project plans to subdivide the permission, so LET’s study the front-end permission first.

The starting point of permission design is that users with different permissions can see different contents and realize different operations.

To the specific design, can be divided into routing level permissions and button level permissions, from the implementation of difficult level, are very simple, this blog is mainly about button level permissions control.

What do button level permissions need to do?

Do permission control, first of all to know what is the purpose to achieve.

Button level permission control is relatively simple, and the buttons and operation functions are different according to different identities.

First, identity identification and verification are performed. Public methods can be extracted based on the user permission categories delivered by the server.

/ /.. /utils/auth.js file location


// Obtain the current customer permission
export function getCurrentAuthority(){...return ["admin"]}// Verify permissions
export function check(authority = []){
    let current = getCurrentAuthority();
    return current.some(item= >item.includes(item))
}

// Login verification
export function isLogin(){
    const current = getCurrentAuthority();
    return current && current[0]! = ="guest";    
}
Copy the code

Two ways to do it

After stripping out the common methods for identity extraction and verification, it can be used in different components. The most brutal method is to directly use v-if to make crazy judgments.

However, this approach is not elegant, and it can confuse the original use of V-if content, so there are two main ways to use permission judgment encapsulation, one is a component, and the other is a directive.

1. Component mode

Since V-IF is not very elegant, is it possible to encapsulate the functions of V-IF? Of course, it is feasible. We only need to nest a layer of components outside the content requiring permission control, and judge whether the inner component is rendered by the outer component, so as to achieve the capability of V-IF we need.

Let’s think about this permission component.

First of all, the permission component does not need to have a specific DOM rendering; its role is to determine whether to render the specific business components it nested based on the criteria. That way, it can be a purely functional component that doesn’t have the template content and just needs the logic, and it can determine the permissions allowed in props by referring to encapsulated permission validation methods.

Component implementation:

<script> import { check } from ".. /utils/auth.js"; export default { name: 'Authorized', functional:true, props: { authority:{ type:Array, required:true } }, render(h, context) { const { props, scopedSlots } = context; return check(props.authority) ? scopedSlots.default() : null }, } </script>Copy the code

Ideas:

In the render function, the content of props and slot is obtained from the context, and the check method is used to check whether the permission passed by props. Then, the content of slot is rendered according to the result to achieve permission control.

Component use:

<template>
    <Authorized :authority="['admin']" >
        <other-components></other-components>
    </Authorized>
</template>
Copy the code

Note: The Authorized component can be used in multiple places and can be registered globally. The specific code is not shown

2. Instruction mode

The use of component permission control, basically can be very good to meet the needs of button level permission control, just need to add components outside the button to control permission.

However, it is still tedious to nest components outside each time. We can refer to V-IF for custom instruction control.

//./directives/auth.js
import { check } from '.. /utils/auth.js';

function install(Vue, options = {}) {
    Vue.directive(options.name || 'auth', {
        inserted(el, binding) {
            if(! check(binding.value)) { el.parentNode && el.parentNode.removeChild(el); }}})}export default { install }
Copy the code

Ideas:

The parameters passed in the binding of the custom instruction are received and verified by the check function. If the verification fails, the parent node of the node where the current instruction is located is obtained to delete the current node and achieve permission control.

Instruction registration:

// main.js
import auth from './directives/auth.js'

Vue.use(auth)
Copy the code

Instruction usage:

<template>
	<other-components v-auth="['admin']"></other-components>
</template>
Copy the code

The advantages and disadvantages

The use of component to achieve permission control, in the permission modification will be more flexible to render the controlled part, while using a little cumbersome;

Directive permission control is simpler to use, but is implemented by deleting DOM nodes, so it is only controlled for the first time.

After the permission is granted, it will not be changed at will. You can choose two different methods according to the application scenario.

The relevant data

1. Vue functional components

2. Customize commands