Loading a directive before the page loads in Vue.js

In my application, I've implemented a directive that dynamically displays buttons based on the user's role permissions:

import { store } from '../store/';
import * as types from '../store/types';

const hide = vnode => {
  if (vnode.elm.parentElement) {
    vnode.elm.parentElement.removeChild(vnode.elm);
  }
};

export const userRole = {
  update(el, binding, vnode) {
    const userId = store.getters[types.GET_USER_ID];
    const { value, modifiers } = binding;
    if (value.role) {
      if (Reflect.has(modifiers, 'manager')) {
        if (value.role[0] !== userId) hide(vnode);
      }
};

Each button in the UI is defined with the following structure:

          <vue-button
            v-userRole.manager="{role: job.role}"
            @click.prevent.stop="e => payoutJob(job.id)"
          >
            Button Text
          </vue-button>

One issue I'm facing is that all buttons are initially displayed upon page load, causing a flash of unnecessary elements before the correct buttons are shown based on user roles. Is there a way to prevent this flashing effect?

I would prefer to have no buttons visible until the logged-in user's role is verified against the directive file.

User information is stored locally, in Vuex, and each page checks for signed-in users during loading.

Answer №1

It seems that the way in which you have structured this process guarantees that the outcome will always be the same - your directive is eliminating the HTML only after it has been generated. To prevent the element from being generated in the first place, consider utilizing a v-if or a similar approach instead. I can identify two potential solutions for resolving this issue: one involves making a minor adjustment to your current setup as a temporary fix, while the other presents a more permanent and effective solution (although the ultimate decision rests with you).

As a workaround, you could designate all of your buttons with a style attribute set to display:none, and then modify your directive to either remove the element entirely or reset the styling (or alter the class assignment, depending on your implementation). This strategy would at least prevent the button from being displayed.

Alternatively, a more robust resolution might involve developing your own component with a userRole property. Within this component, implement the verification process mentioned earlier (potentially through a computed property) to determine whether to display or conceal the component based on specific conditions.


UPDATE

To evaluate the underlying principles of your technique, I conducted a brief test via a fiddle. Simply adjusting the hook from update to inserted may offer a possible resolution. Keep in mind that your actual code may be more intricate, so results may vary ;).

Answer №2

If you're looking to dive deeper into Vue instance functionality, I recommend checking out the documentation at https://v2.vuejs.org/v2/guide/instance.html. One approach could be using the beforeCreate method.

Another suggestion, inspired by Euan Smith, is utilizing v-if and storing true/false values in your data based on loading rights (initialize as false and update to true when applicable).

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

The password encryption method with "bcrypt" gives an undefined result

import bcrypt from 'bcrypt'; export default class Hash { static hashPassword (password: any): string { let hashedPassword: string; bcrypt.hash(password, 10, function(err, hash) { if (err) console.log(err); else { ha ...

Prevent certain images from loading by blocking them

I am trying to create an extension that blocks two specific images from loading. Initially, I attempted to achieve this by using the following code in the content.js file: $("#rated-image").remove(); //id of one image $(".blur-mask").remove(); //class of ...

Sorry, but we couldn't locate the page you were looking for. The robots.txt file seems

Hey there everyone, I'm currently working with Nuxt3 and encountering an error when trying to access the robot.txt file. Here's the Robot.txt module that I've integrated. Within my nuxt.config.ts file: export default defineNuxtConfig({ ...

How come props do not get updated along with state changes?

I've encountered an issue where the state of a component being passed into another component as a prop is not updating correspondingly. Various attempts have been made to resolve this, including placing it in the return function and updating the "low ...

Tips for converting a flat JavaScript array into a multidimensional one

I'm working on an example where I need to change some values. Here is the link to access it: http://jsfiddle.net/k83hj1jb/ The current output is a flat array: [ {"name":"options[11][140]","value":"140"}, {"name":"options[8][99]","value":"99" ...

Exploring the Depths of Multidimensional JSON Arrays in PHP

I am currently working on developing a web-based file manager that allows me to organize, view, create, edit, and delete folders and files. In order to store information about these folders, files, and subfolders, I am in need of an appropriate data struct ...

Automatically dismiss a Modal Popup without the need for a button or click event

I am currently facing an issue where I have a page constantly refreshing, and I am looking to implement a modal popup with a message saying "Please wait..." while the page reloads using $state.reload(). GenericModalService.confirmationSplit($rootScope, m ...

Retrieve JSON data for the initial request and showcase it on the homepage

After recently diving into Vue.js for the first time, I encountered a need to serialize Django objects. views.py def articles(request): model = News.objects.all() # obtaining a list of News objects modelSerialize = serializers.serial ...

How should we provide the search query and options when using fuse.js in an Angular application?

Having previously utilized fuse.js in a JavaScript project, I am now navigating the world of Angular. Despite installing the necessary module for fuse.js, I'm encountering difficulties implementing its search functionality within an Angular environmen ...

Adjust the speed of the remaining divs below to move up when one is deleted using Ajax and jQuery

My div elements are arranged from top to bottom, and when one selected div is removed or faded out, all other divs below it shift up suddenly to fill the gap. While this behavior is functional, I would prefer to slow down the movement of the divs shifting ...

The HTML modal window is experiencing loading issues

I am attempting to implement a modal box that appears on click in an HTML document. The HTML code looks like this: <a href="#openModal">Open Modal</a> <div id="openModal" class="modalDialog"> </div> <a href="#openModal">O ...

The MUI date picker does not display dates earlier than 1900

I am in need of a datepicker that allows users to select dates from the 1850s, however, the mui datepicker only starts from the 1900s. To demonstrate this issue, I have provided a sample code in this codesandbox I am utilizing mui in the remainder of my ...

Switching the body's background image dynamically using javascript

I'm attempting to switch up the background image using JavaScript. Here's how I've defined the background: body { background: black; overflow-x: hidden; overflow-y: hidden; } body:before { overflow-x: hidden; overflow ...

When working on a REST APIs project with ReactJS fetch and NodeJS, I am encountering difficulties in reading authorization headers on the server side

I'm having issues retrieving headers on the server side using ReactJS fetch to call an API on the front end. In my old project, this functionality was working perfectly fine. I'm puzzled as to why it's not working now, especially since I hav ...

What is the best way to obtain an attribute name that is reminiscent of Function.name?

My objective is to securely type an attribute. For example, I have an object: const identity = { address: "Jackie" }; At some point, I will rename the address key to something else, like street_address. This is how it is currently implemented ...

Use Javascript to automatically zoom into a specific div element when the page loads

Encountering a rather unusual problem here that I couldn't seem to find any solutions for on Google. What I want is for a scene to be zoomed into when the page loads. Just picture this scenario: initially, the image below occupies 100% of the window ...

Is it possible to use a Jade block extension for every individual item in the database?

What's the issue here? test.jade doctype !!! 5 html(lang="en-us") head title test h1 Information; body block testcontent form(method="post") input(type="button", value="refresh") testcontent.jade ...

Efficiently importing SCSS files into Vue single file components using Webpack without redundancy

Encountering a problem with my Vue SFCs where accessing a scss file results in duplicated styles leading to large css bundles and crashing Dev Tools during style debugging. Using Webpack 4 and webpack-dev-server for development services with hot reload, w ...

I currently possess a certain document stored in the database. Is there a way to create a query using mongoose that will allow me to remove an item from the "cart" array within this document?

In this post request, the intention is to remove the item from the "cart" array by identifying it with the product "id". .post('/delete', async (req, res) => { if (await UserProfile.findOneAndDelete({ 'cart.id': req.body.id })) { ...

utilizing axios encoding settings within vue.js

I am currently utilizing vue.js along with axios to retrieve data from an API endpoint. The specific URL I require is structured like this: https://base_url.com?f=json&where=&returnGeometry=false&spatialRel=esriSpatialRelIntersects&geometr ...