Vue based on Element button permission implementation solution

Vue based on Element button permission implementation solution

Background requirements: The ERP system needs to add a "button permission control" function, and the control granularity of permissions should be extended to the button level.

expected

There are two interactive modes for button permission control: "invisible" and "visible but not clickable".

Invisible

The invisible interaction method is relatively simple. We can use v-if to control whether it is displayed. You can use v-show, but it is not safe enough. After all, v-show only changes the style to display: none, and it still exists in the real DOM rendering, so it is recommended to use v-if to control the invisible.

Visible but not clickable

"You can see, but you can't."

  • Style control (you need to add a disabled style), such as cursor: not-allowed, graying out, etc.
  • Not clickable, that is, to disable or block click events, it seems that preventDefault/stopProgration can achieve this;

The final product requirement chose "visible but not clickable", probably because invisible was considered too simple. (¬_¬)

Idea Exploration

  • Add a wrapper function to the callback function of the button click event to control its permissions and intercept and trigger the event. It is like making a proxy, which is a bit like a high-order component (but it changes the existing business too much, and each @click binding function must be modified one by one, so this solution is abandoned);
  • To prevent the button click event from bubbling and triggering, it seems that preventDefautl/stopProgration can be used. It feels like the event can be monitored on the DOM element in the form of instructions. If it is allowed, the event will be executed normally, otherwise it will be blocked;

Practice plan

Finally, we chose the instruction method to expand at the lowest cost and avoid changing the existing business code logic.
Elements that need click hijacking for permission control:

  • el-button
  • btn-wrapper (self-encapsulated component)
  • div/span/a etc tags

Please see below for the specific implementation plan:

Permission entry: Vuex control, global use

//After the user logs in, get the user's permission CODE code and store it in the store
this.$store.commit('SET_AUTH_CODE', authCodeList);

SET_AUTH_CODE: (state, acthCode) => {
 if (acthCode) {
   state.autoCodeList = acthCode;
 }
 setStore({
  name: 'autoCodeList',
  content: state.autoCodeList || [],
 });
}

Defining permission instructions

const disableClickFn = (event) => {
  event && event.stopImmediatePropagation();
}

export const hasPermission = () => {
  Vue.directive('permission', {
    bind(el, binding) {
      let disable = true;
      if (autoCodeList.length && autoCodeList.includes(binding.value)) {
        disable = false;
      }

      if (disable) {
        el.classList.add('permission-disabled');
        el.setAttribute('disabled', 'disabled');
        el.addEventListener('click', disableClickFn, true);
      }
    },
    unbind(el) {
      el.removeEventListener('click', disableClickFn);
    }
  });
};

  • First, we use useCapture as true in the third parameter of addEventListener to trigger it during the capture phase, so the event listener here will take precedence over @click to trigger the callback;
  • Secondly, stopImmediatePropagation is used to prevent event bubbling and the triggering of other listeners of the same event;

If multiple event listeners are attached to the same event type on the same element, they will be called in the order in which they were added when the event is triggered. If you call stopImmediatePropagation() in one of the event listeners, the remaining event listeners will not be called. MSDN - stopImmediatePropagation

Add disabled CSS styles

.permission-disabled {
  position: relative;
  cursor: not-allowed !important;
  pointer-events: none; // Prevent elements from receiving mouse events border:none;
  background-image: none;
  &::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 0px;
    right: 0px;
    height: 100%;
    z-index: 9;
    background: rgba(255, 255, 255, 0.5);
  }
}

A relatively unfamiliar CSS property, pointer-events, is used here.

The CSS3 pointer-events property specifies under what circumstances (if any) a particular graphic element can become the target of a mouse event. For more usage reference: MSDN - pointer-events

The use of pointer-events here is just an auxiliary function. It does not necessarily mean that the event listener on the element will never be triggered. If the descendant element has specified pointer-events and allows to become the event target, the parent element event can be triggered. And relying solely on CSS properties to control not clicking is still risky, so it is only used for auxiliary purposes here.

Global "permission judgment" tool function

import { getStore, } from '@/util/store';
const autoCodeList = getStore({ name: 'autoCodeList', }) || [];

export function hasPermission(authName) {
  return !(autoCodeList.length > 0 && autoCodeList.includes(authName));
}

Specific use

// Command method (oms/order/save here corresponds to the CODE permission code when the user logs in)
<el-button v-permission="'oms:order:save'">Save</el-button>

// Function method <el-button :disabled="hasPermission('oms:order:save')"></el-button>

This is the end of this article about the implementation of Vue-based Element button permissions. For more relevant Element button permissions, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Vue+elementUI component recursively implements foldable dynamic rendering multi-level sidebar navigation
  • Example code of vue + element ui to realize player function
  • Analysis of Vue element background authentication process
  • Vue+element+oss realizes front-end fragment upload and breakpoint resume
  • Solve the problem that the element DateTimePicker+vue pop-up box only displays hours
  • Vue imitates ElementUI's form example code
  • An example of implementing a tree component using Vue
  • Specific use of Vue+iview using tree controls
  • Implementation code of editable tree table in Vue
  • Vue Element front-end application development tree list component

<<:  Solution to the problem that the configuration file my.cnf in MySQL cannot be started due to permission issues

>>:  Docker uses busybox to create a base image

Recommend

In-depth understanding of Vue's plug-in mechanism and installation details

Preface: When we use Vue, we often use and write ...

Solution to MySQL Chinese garbled characters problem

1. The Chinese garbled characters appear in MySQL...

How to use the jquery editor plugin tinyMCE

Modify the simplified file size and download the ...

getdata table table data join mysql method

public function json_product_list($where, $order)...

Modification of time zone problem of MySQL container in Docker

Preface When Ahhang was developing the Springboot...

An example of how to write a big sun weather icon in pure CSS

Effect The effect diagram is as follows Implement...

Implementing a simple Gobang game with native JavaScript

This article shares the specific code for impleme...

How to turn off eslint detection in vue (multiple methods)

Table of contents 1. Problem Description 2. Probl...

Install and build a server environment of PHP+Apache+MySQL on CentOS

Yum (full name Yellow dog Updater, Modified) is a...

Let's talk in detail about how the NodeJS process exits

Table of contents Preface Active withdrawal Excep...

Sample code for highlighting search keywords in WeChat mini program

1. Introduction When you encounter a requirement ...

Some things to note about varchar type in Mysql

Storage rules for varchar In versions below 4.0, ...