The parentNode of el in the vue directive is null

In the project, I suddenly found that when using vue custom instructions, I found that the parent element parentNode of the element el became null.

Vue2.x part:

Code:

function checkPermission(el, binding) {
    const { value } = binding
    if (value) {
        const arr = value.split(',')
        if (arr.length >= 2 && !hasPermission(arr[0], arr[1])) { // 判断权限
            el.parentNode && el.parentNode.removeChild(el)
        }
    } else {
        throw new Error(`need roles! Like v-permission="'delete'"`)
    }
}

export default {
    bind(el, binding) {
        checkPermission(el, binding)
    },
    update(el, binding) {
        // checkPermission(el, binding)
    },
}

The original one I used here was the bind hook function.

      vue2.x directive

hook function

An instruction definition object can provide the following hook functions (all optional):

bind: Called only once, when the directive is bound to an element for the first time. One-time initialization settings can be performed here.

inserted: Called when the bound element is inserted into the parent node (only the parent node is guaranteed to exist, but it may not have been inserted into the document).

update: Called when the VNode of the component is updated, but it may occur before its child VNode is updated. The value of the directive may or may not have changed. But you can ignore unnecessary template updates by comparing the values ​​before and after the update (see below for detailed hook function parameters).

componentUpdated: Called after all the VNode of the component where the instruction is located and its sub-VNodes have been updated.

unbind: Called only once, when the instruction is unbound from the element.

At this time, you need to change the hook function to inserted to solve the problem.

import store from '@/store'

export const hasPermission = (routeName, key) => { // 获取按钮是否有权限
    return store.getters.addRouters.some(router => (router.name == routeName && router.meta.buttons && router.meta.buttons.some(btn => btn.frontKey == key)) 
		|| (router.children && router.children.some(child => (child.name == routeName && child.meta.buttons && child.meta.buttons.some(btn => btn.frontKey == key)) 
			|| (child.children && child.children.some(m3 => m3.name == routeName && m3.meta.buttons && m3.meta.buttons.some(btn => btn.frontKey == key)))
				)
			)
	); // addRouters.some(
}

function checkPermission(el, binding) {
    const { value } = binding
    if (value) {
        const arr = value.split(',')
        if (arr.length >= 2 && !hasPermission(arr[0], arr[1])) { // 判断权限
            el.parentNode && el.parentNode.removeChild(el)
        }
    } else {
        throw new Error(`need roles! Like v-permission="'delete'"`)
    }
}

export default {
    inserted(el, binding) {
        checkPermission(el, binding)
    },
    update(el, binding) {
        // checkPermission(el, binding)
    },
}

Vue3.x part:

Code:

function checkPermission(el:any, binding:any) {
    const { value } = binding
    if (value) {
        const arr = value.split(',')
        console.log(hasPermission(arr[0], arr[1]));
        if (arr.length >= 2 && !hasPermission(arr[0], arr[1])) { // 判断权限删除按钮
            el.parentNode && el.parentNode.removeChild(el)
        }
    } else {
        throw new Error(`need roles! Like v-permission="'delete'"`)
    }
}

export default {
    created(el:any, binding:any, vnode?:any) {
        checkPermission(el, binding)
    },
    updated(el:any, binding:any, vnode?:any) {
        checkPermission(el, binding)
    },
}

The original one I used here was the bind hook function.

vue3.x directive

hook function

Create is called before the attribute of the bound element or before the event listener is applied.

beforeMount is called before the element is inserted into the DOM

Mounted is called after the parent component of the bound element and all its own child nodes are mounted.

beforeUpdate is called before the parent component of the bound element is updated.

updated is called after the bound element's parent component // and all its own child nodes have been updated

beforeUnmount is called before the parent component of the bound element is unmounted

Unmounted is called after the parent component of the bound element is unloaded.

At this time, you need to change the hook function to mounted to solve the problem.

import store from '@/store'

export const hasPermission = (routeName:any, key:any) => { // 获取按钮是否有权限-目前权限buttons位置在第一层 没有在meta中
    // const routeName = router.app.$route.name
    return store.getters.GET_MENU.some((router:any) => (router.path == routeName && router.buttons && router.buttons.some((btn:any) => btn.frontKey == key)) || (router.children && router.children.some((child:any) => (child.path == routeName && child.buttons && child.buttons.some((btn:any) => btn.frontKey == key)) || (child.children && child.children.some((son:any) => son.path == routeName && son.buttons && son.buttons.some((btn:any) => btn.frontKey == key)))))
	);
}

function checkPermission(el:any, binding:any) {
    const { value } = binding
    if (value) {
        const arr = value.split(',')
        console.log(hasPermission(arr[0], arr[1]));
        if (arr.length >= 2 && !hasPermission(arr[0], arr[1])) { // 判断权限删除按钮
            el.parentNode && el.parentNode.removeChild(el)
        }
    } else {
        throw new Error(`need roles! Like v-permission="'delete'"`)
    }
}

export default {
    mounted(el:any, binding:any, vnode?:any) {
        checkPermission(el, binding)
    },
    updated(el:any, binding:any, vnode?:any) {
        checkPermission(el, binding)
    },
}

Guess you like

Origin blog.csdn.net/jiangzhihao0515/article/details/127213894