If the condition is not met, Vue directive will skip rendering the element

I've decided to create my own system for managing roles and rights in Vue since the existing options are not meeting my needs.

Currently, I am able to hide an element when a user lacks the necessary role, but what I really want is to completely prevent the component from being rendered. However, I'm unsure of how to accomplish this.

The code snippet below shows what I have so far:

app.directive('hasRole', hasRole)
import {useUserStore} from "@/stores/UserStore.js";

export default {
    // called before bound element's attributes
    // or event listeners are applied
    created(el, binding, vnode, prevVnode) {
        //console.log(el, binding, vnode, prevVnode)
    },
    // called right before the element is inserted into the DOM.
    async beforeMount(el, binding, vnode, prevVnode) {
        const userStore = useUserStore()
        await userStore.fill()
        console.log(userStore.getUser.roles.includes(binding.value))
        if (!userStore.getUser.roles.includes(binding.value)) {
            // el.style.display = 'none'; <---- this hides the element, so that works.
            vnode = null
            return el = null;
            el.style.display = 'none';
        }
    },
    // called when the bound element's parent component
    // and all its children are mounted.
   mounted(el, binding, vnode, prevVnode) {
        //console.log(el, binding, vnode, prevVnode)
    },
    // called before the parent component is updated
    beforeUpdate(el, binding, vnode, prevVnode) {
        //console.log(el, binding, vnode, prevVnode)
    },
    // called after the parent component and
    // all of its children have updated
    updated(el, binding, vnode, prevVnode) {
        //console.log(el, binding, vnode, prevVnode)
    },
    // called before the parent component is unmounted
    beforeUnmount(el, binding, vnode, prevVnode) {
        //console.log(el, binding, vnode, prevVnode)
    },
    // called when the parent component is unmounted
    unmounted(el, binding, vnode, prevVnode) {
        //console.log(el, binding, vnode, prevVnode)
    }
}

If anyone knows how to prevent the rendering of the component altogether, please share your insight.

Answer №1

Your existing user store is designed to be injected into any component seamlessly.

I recommend calculating commonly used keys such as isAdmin, isSuperAdmin within the store:


const isAdmin = computed(() => hasRole('admin'))

Within your components, you can utilize the following pattern to conditionally display items:

<template>
<div v-if="isAdmin">
  <h1>Highly Confidential Information</h1>
</div>
</template>

<script setup>
const { isAdmin } = useUserStore()
</script>

This approach avoids direct manipulation of the DOM, which is typically cumbersome and often considered poor practice.

Answer №2

In my opinion, employing directives for this specific purpose may not be the optimal approach to prevent component rendering.

Instead of using directives, consider utilizing the v-if condition to prevent a component from being rendered.

To streamline the logic of the hasRole function across multiple components, you can leverage mixins or develop a lightweight plugin that can be integrated into your Vue application.

Answer №3

This is the updated code snippet with corrections.

import {useUserStore} from "@/stores/UserStore.js";

export default {
  inserted(el, binding, vnode) {
    const { value } = binding
    const super_admin = "admin";
    const userStore = useUserStore()
    await userStore.fill()
    const roles = userStore.getUser.roles

    if (value && value instanceof Array && value.length > 0) {
      const roleFlag = value

      const hasRole = roles.some(role => {
        return super_admin === role || roleFlag.includes(role)
      })

      if (!hasRole) {
        el.parentNode && el.parentNode.removeChild(el)
      }
    } else {
      throw new Error(`Missing role value"`)
    }
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for utilizing JavaScript to engage with a Cisco call manager

Our team is currently working on an IVR web application built with node js. I am wondering if it is feasible to integrate with the cisco unified call manager directly through node js in our web application? ...

Choosing a portion of a polyline - Google Maps Application Programming Interface

Is it possible to select only a section of a polyline in a Google Map? I have markers that are added by the user and a polyline is drawn between the markers. The polyline between two markers represents the route between the two places. I want the user to b ...

Utilize the onClick Event to Trigger Function with an Array in ReactJS

Every time I attempt to pass an array as a value to a function by clicking on a div, I encounter the error below: Uncaught Invariant Violation: Expected onClick listener to be a function, instead got a value of object type. If passing an array to a fun ...

Showing a coordinated timer countdown alongside automatic server-side logout

I found inspiration in this particular PHP session timer example that incorporates an AJAX call to monitor the session's 'time'. I aim to integrate a simple JavaScript countdown timer for the user, like so: function startTimer(duration, di ...

React erroneously encodes quotation marks within attribute names

Currently, I am working on a Next.js / (SSR React) application. I am passing a property through props to a meta component. The specific tag where the string is inserted looks like this: <meta property="og:description" content={ `${description}` } /& ...

Scripts are only able to close the windows that they themselves have opened as a way to work around

I have been utilizing the reactjs popup library and incorporated the following code: <Popup trigger={<a href="javascript:void(0)">bobby</a>} modal> <button className="close" onClick={close}> &time ...

Creating an HTML file with a JavaScript source file embedded within using Express

Currently, in my nodeJS application with expressJS, I am encountering an issue when attempting to render an HTML file containing JavaScript code (src="../../viewer/something.js") to a browser from a route requested by a client. The error message received ...

Having trouble getting the Javascript dropdown script to work on a Wordpress page?

Hello all, I've been experimenting with creating a simple dropdown menu for my Wordpress website. The idea is that when a user clicks on a specific text, a dropdown menu with various links will appear. I followed the guidance from W3 Schools, but unfo ...

I would greatly appreciate some guidance on asp.net and javascript

I am just starting out with JavaScript and facing some challenges. Currently, I'm struggling to develop a Mouseover and mouseout script. Here is my ASPX code: <div> <div id="div_img" style="height: 300px; width: 300px; border: solid 1p ...

Why is my JQuery UI droppable accept condition failing to work?

After scouring the internet for hours, I'm still stuck and can't seem to figure out what's wrong with my code: Here's the HTML snippet: <ul style="list-style:none;cursor:default;"> <li>uuu</li> <li>aaa& ...

Is there a way to prevent Express from automatically adding a slash to a route?

Despite my extensive search for a solution, none of them have proven effective. Perhaps you could provide some assistance. I'm currently working on a Node.JS and Express-based plugin webserver. The main code for the webserver is as follows: This sec ...

Using Zombie.js to simulate clicking on a Javascript link

I am currently using Node.js in combination with Zombie.js for web scraping. There are certain pages on which I need to interact with JavaScript links. For instance, consider the following page: http://www.indotrading.com/company/berkat-jaya-electronics. ...

What is preventing the successful insertion of a JSON array into a SQL database?

I am facing an issue with inserting a JSON array into an SQL database. I have an HTML table that stores its data in a JavaScript array, converts it to a JSON array, and then sends it to a PHP file. However, when trying to insert this JSON array into the da ...

Determine the total of the values in an array by adding or subtracting them

I am currently working on a form that contains approximately 50 similar elements organized in a table. Each item in the table consists of three records. The elements are retrieved from the database and displayed in the table using the following code: ...

Angular - Enhance ngFor index while filtering

I am currently working with a list that utilizes an *ngFor loop in the template: <li *ngFor="let product of products | filterProducts: selectedFilter; index as productId"> <a [routerLink]="['/product', productId]"> {{produc ...

What causes a "UnhandledPromiseRejectionWarning" while using Puppeteer?

What causes the following warnings to appear, and how can I resolve them? Warnings: (node:26771) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Protocol error (Runtime.callFunctionOn): Target closed. (node:26771) ...

Encountering 404 errors in production when using vue-router with Node.js for URL paths

While trying to deploy a multipage vue3 frontend to an application, everything seems to work fine in development mode. However, when I switch to production and attempt to navigate to a specific URL through the search bar - like , I encounter a 404 error. ...

Idle Time in Nextjs - Making the Most of D

I've been experiencing a significant delay of around 6 seconds when refreshing my Next.js platform. As part of my debugging process to identify the root cause of this issue, I uncovered that approximately 5 seconds of this time is classified as idle. ...

Is there a way to keep a JS script running even after navigating away in the Google Chrome console?

Assume there is a basic script available var x = 0; run(); function run() { console.log(x++); setTimeout(run, 1000); } If I input it into the Google Chrome console. How can I keep it running even after navigating to another page (continuously d ...

How come the button doesn't get enabled after three seconds even though ng-disabled is being used?

index.html <html ng-app='myApp'> <head> <title>TODO supply a title</title> <script src="js/angular.js" type="text/javascript"></script> <script src="js/using built-in directives. ...