Background requirements: The ERP system needs to add the "button permission control" function, and the granularity of the control of permissions should be popularized to the button level.
expected
There are only two ways of interaction between button permission control: "invisible" and "visible and unpointable".
Not visible
The invisible interaction method is relatively simple, and we can use v-if to control whether it is displayed. Using v-show is OK, but it is not safe enough. After all, v-show just changes the style to display: none, which still exists in real DOM rendering, so it is recommended to control invisibility by v-if.
Visible and not pointable
"You can watch it, but you can't."
- Style control (you have to add a disabled style), cursor: not-allowed, graying and so on;
- Unclickable, that is, to disable or block click events, it seems that preventDefault/stopProgration can be implemented;
The final product demand is chosen to be "visible but not pointable", and the reason may be that it is too simple to think that invisible. (¬_¬)
Exploration of ideas
- Give the callback function of the button click event, add a wrapper function, control its permissions, and intercept and trigger events. It's quite like being an agent, which is a bit like a high-level component (but it's too much changes to the existing business, so you have to modify each @click binding function one by one, so you give up the solution);
- It prevents the button click event from bubbled and triggering, and it seems that preventDefautl/stopProgration can be used. It feels that the event can be monitored by commands. If allowed, the event will be executed normally. If not allowed, the event will be blocked;
Practical Plan
Finally, the instruction method was selected to expand at the minimum cost and avoid changing the existing business code logic.
Elements that require click hijacking for permission control:
- el-button
- btn-wrapper (self-encapsulated component)
- div/span/a etc. tags
For specific implementation plans, please see below:
Permission portal: Vuex control, global use
// After the user logs in, obtain the user's permission CODE code and store it in the storethis.$('SET_AUTH_CODE', authCodeList); SET_AUTH_CODE: (state, acthCode) => { if (acthCode) { = acthCode; } setStore({ name: 'autoCodeList', content: || [], }); }
Define permission directives
const disableClickFn = (event) => { event && (); } export const hasPermission = () => { ('permission', { bind(el, binding) { let disalbe = true; if ( && ()) { disable = false; } if (disable) { ('permission-disabled'); ('disabled', 'disabled'); ('click', disableClickFn, true); } }, unbind(el) { ('click', disableClickFn); } }); };
- First, addEventListener is the third parameter. We use useCapture to true to let it fire in the capture stage, so the event listener here will give priority to @click to trigger the callback;
- Secondly, stopImmediatePropagation is used to prevent event bubbles and other triggers of the same event listeners;
If multiple event listeners are attached to the same event type of the same element, when this event is fired, they are called in the order in which they are added. If stopImmediatePropagation() is executed in one of the event listeners, none of the remaining event listeners will be called.MSDN - stopImmediatePropagation
Add disabled CSS styles
.permission-disabled { position: relative; cursor: not-allowed !important; pointer-events: none; // Prevent elements from becoming 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); } }
Here we use a relatively unfamiliar CSS property, pointer-events.
The pointer-events property of CSS3 specifies under what circumstances (if any) a specific graphical element can become a target for mouse events. For more usage references:MSDN - pointer-events
The use of pointer-events here is just an auxiliary function, and does not necessarily mean that the event listener on the element will never trigger. If the descendant element has specified pointer-events and is allowed to be the target of the event, it is still risky to trigger the parent element event, and rely solely on the CSS attribute to control the non-click, so it is only used as an auxiliary function here.
Global "Permissions Decision" tool function
import { getStore, } from '@/util/store'; const autoCodeList = getStore({ name: 'autoCodeList', }) || []; export function hasPermission(authName) { return !( > 0 && (authName)); }
Specific use
// Command method (the oms/order/save here is 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 article about vue's Element button permission implementation solution. For more related Element button permission content, please search for my previous article or continue browsing the related articles below. I hope everyone will support me in the future!