0

We developed a Vue custom directive that replaces DOM elements with a comment depending if the user has permission for specific information. This directive works fine when we use it in any DOM element, but when we apply it to another Vue component it doesn't work as expected because the mounted() function gets called, which we don't want

The problem really is that we don't want to render that component, specifically if it has an API call because this makes the whole system fail.

Here is the directive code:

Vue.directive("checkPermission", {
    bind: (el, binded, vnode) => {
        let permissions = self.$nuxt.$store.$auth.user.permissions;

        if (
            !self.$nuxt.$store.$auth.user.isAdmin &&
            permissions &&
            permissions.length > 0
            ) {
            let hasPermission = false;
            const { action, subject } = binded.value;

            hasPermission = permissions.some(
                permmission =>
                    permmission.action === action &&
                    (Array.isArray(subject) ? subject.includes(permmission.subject) : permmission.subject === subject)
            );

            if (!hasPermission) {
                const comment = document.createComment(" ");

                Object.defineProperty(comment, "setAttribute", {
                    value: () => undefined
                });

                vnode.text = " ";
                vnode.elm = comment;
                vnode.isComment = true;
                vnode.context = undefined;
                vnode.tag = undefined;
                vnode.data.directives = undefined;
                vnode.children = undefined

                if (vnode.componentInstance) {
                    vnode.componentInstance.$el = comment;
                }

                if (el.parentNode) {
                    el.parentNode.replaceChild(comment, el);
                }
            }
        }
    },
2
  • Why using "a comment" to hide your component over a simple v-if ? Commented Feb 25, 2022 at 18:08
  • 1
    It's more elegant to use the custom directive, otherwise we would be repeating a lot of code in all of our components just to check if the user has the necessary permissions. Of course we could abstract the function in another file and import it in every component but why not use the directive? That would be way simpler. Also we don't want to just "hide it", we need it to not be rendered Commented Feb 25, 2022 at 18:18

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.