Issue encountered in Vuejs when attempting to remove a component using directives while the mounted or created event is still being executed

I created a custom directive that functions like v-if. In the directive, I check access rights and remove the element if access is not granted.

Below is my code:

Vue.directive('access',  {
    inserted: function(el, binding, vnode){

        //check access

        if(hasAccess){
           vnode.elm.parentElement.removeChild(vnode.elm);
        }
    },

});

vue file

<my-component v-access='{param: 'param'}'>

The problem I'm facing is that when applying this directive to a component, it removes the component but the functions called by the created/mounted hook still execute.

Within the component (my-component), there are functions in the mounted/created hook that get executed even after the component is removed. I want to prevent these functions from running. Is there a way to stop the execution of the mounted/created events?

Answer №1

Replicating the behavior of v-if in a custom directive is not feasible. Directives are limited to affecting the DOM element they are attached to and cannot control the rendering of vnodes. (v-if differs from a directive as it generates conditional rendering code during template compilation.)

While I recommend avoiding the following suggestions if possible, I will still provide them as they align closely with your desired functionality.

1. Implement a Global Method through Vue Prototype Extension

Utilize v-if for conditional rendering. Create a global helper method within the Vue prototype that calculates access permissions.

Vue.prototype.$access = function (param) {
  // Calculate access according to requirements
  // ('this' refers to the component instance where the function is called)
  return ...
}

Use this method in templates like so:

<my-component v-if="$access({ param: 'param' })">

2. Define Method in Root Component Instead of Vue Prototype

This approach is similar to #1 but avoids cluttering the Vue prototype by defining the method only in the root instance:

new Vue({
  el: '#app',
  render: h => h(App),
  methods: {
    access(param) {
      return ...
    }
  }
})

Use the method in templates like this:

<my-component v-if="$root.access({ param: 'param' })">

This way, the method's origin is better identified.

3. Explore Usage of a Global Mixin

Although not optimal, consider investigating the practicality of utilizing a global mixin.

4. Implement a Custom Component for Access Calculation

Create a custom component, preferably functional, to calculate access for specific areas in your template:

Vue.component('access', {
  functional: true,
  props: ['param'],
  render(h, ctx) {
    // Calculate access based on input props
    const access = calculateAccess(ctx.props.param)

    // Provide access to the default scoped slot
    return ctx.scopedSlots.default(access)
  }
})

Use this custom component in templates as follows:

<access :param="param" v-slot="access">
  <!-- Utilize 'access' within this section -->
  <div>
    <my-component v-if="access"></my-component>
  </div>
</access>

Since <access> is a functional component, it behaves more like a function than an actual component instance.

Although possibly excessive for your current needs, this option may be useful in complex scenarios.

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

Transmit data from a child component to a Vue JS page through props, and trigger the @blur/@focus function to access the prop from the parent component

Seeking guidance on working with props in Vue JS. As a newcomer to Vue, I hope that my question is clear. I've included my code snippet below, but it isn't functioning correctly due to missing Vue files. In my attempt to use a prop created in t ...

Show a caution message when there has been no activity on the page for 3 minutes

I am currently developing a PHP page that includes timed tests. The maximum duration for a test is 1 hour, however the session times out after just 10 minutes of inactivity. Interestingly, when the timeout occurs, the test page does not automatically refre ...

JavaScript alerts

Can anyone recommend a quality library with beautifully animated popups? Specifically, I need a popup that allows for basic HTML fields such as text areas and more.... I am in search of a popup that will overlay on the current page, rather than opening a ...

Node.js - Creating seamless integration between Sequelize model JS and controller TS

Having trouble making my User.js model recognized inside my UserController.ts with sequelize in TypeScript. Edit: Unable to change the file extensions for these files. In the await User.findAll() part, an error occurs when running on the server, stating ...

Leveraging the 'this' keyword in TypeScript

In my Javascript class, I used the 'this' keyword as shown below: if (this[this.props.steps[i].stepId].sendState !== undefined) { this.setState({ allStates: { ...this.state.allStates, [thi ...

Can someone explain the process of unescaping characters in an API response to me?

I have created an application that leverages AngularJS to pull data from the WP Rest API V2. The response includes escaped characters, like the example below: "excerpt": { "rendered": "<p>When we go shopping, we encounter many different labeling ...

Tips for preventing child elements from becoming distorted when the parent element is resized

How can I prevent rotated child elements from skewing when the parent element is scaled? Here is the code snippet that I am working with: <svg viewbox="0 0 500 500"> <g class="parent" transform="matrix(1.71341 0 0 1 -42.302 0)"> <path ...

Produce a vue attribute

I am looking to display a property in my component. My template includes: <v-flex v-for="c in components"> <component :is="c.component" v-bind="c.prop"></component> </v-flex> And in the script: ... mounted(){ ...

Update the html() function to include any content that has been typed into a

I have a webpage structured like this: <div id="report_content"> Some information <textarea name="personal"></textarea> <b>Other information</b> <textarea name="work"></textarea> </div> Whe ...

Obtaining a file that includes a selection of documents that correspond to a specific search criteria, along with the overall number of

Is it possible to query a collection to retrieve both a limited number of documents matching a query and the total amount of documents that match the query at the same time? This is the desired result: { result : [ { _id:null, ...

Tips on invoking a mixin within a Jade template showcased in a Node/Express endpoint

I'm currently developing a component that I plan to use multiple times on a website through a Jade template. This is how my route is set up: router.get('/', function(req, res, next) { res.render('indicators',{category:"", num ...

Is it necessary to perform a specific action if the text within a div matches pre

I've been struggling to make this work properly. Even after removing the AJAX POST function, the issue persists. No alerts or any indication of what's going wrong. Check out the code on JSFiddle: HTML <div class="notification"> ...

Vue.js provides an interesting object that contains observed data

My axios request looks like this: retrieveData() { Axios.get( '/vue/get-data/', { ...

Navigating a intricate JSON structure using JavaScript - the ultimate guide!

I am facing a challenge with a complex JSON object that I need to traverse and add additional properties to. Below is an example of the JSON structure: Object {root: Object} root: Object entity_children: Array[1] 0: Object ...

Launch target _blank within a modal instead of a new tab

I'm currently exploring ways to use vanilla JavaScript in order to display all external links - particularly those that typically open in a new tab or window - within a modal box instead. My goal is to implement a listener on external links (those no ...

Guide to programmatically configuring meta title, description, and image in a Vue.js project with the help of Vue Unhead and Vue Meta

I'm currently developing a Vue.js project where I need to dynamically set the meta title, description, and image based on data fetched from an API. To handle the meta tags, I am utilizing Vue Vue Unhead along with Vue Meta. Below is a snippet of the r ...

The constructor for audio in Next JS cannot be found

I'm facing an issue and struggling to find a solution. My project follows the standard structure of Next JS. In the root directory, I have included a components folder. Within the components folder, there is a component with the following code: imp ...

Can Conditional Compilation be Implemented in a Vue.js Project?

When it comes to Vue.js projects, is there a way to differentiate builds for different environments using similar "flags" as in Swift/iOS development? For instance: #if STAGING // one set of logic here #endif #if PRODUCTION // another set of logic he ...

.class selector malfunctioning

I'm currently developing a card game system where players can select a card by clicking on it and then choose where to place it. However, I've encountered an issue where nothing happens when the player clicks on the target place. Here is the li ...

Encountered an issue while attempting npm install, with the error message "Error: Undefined variable standalone_static_library in binding.gyp" and node-sass chokidar error

I've been working on updating a Ruby on Rails and React project from 3 years ago. However, I encountered an issue while trying to npm install. $ npm install gyp: Undefined variable standalone_static_library in binding.gyp while trying to load binding ...