能否封装一个类似 v-if 的自定义指令?

我需要封装一个权限控制指令,当前代码如下:

    app.directive('auth', {
      mounted(el, binding) {
        const permissionNames: string[] = [];
        if ('string' === typeof binding.value) {
          permissionNames.push(binding.value);
        } else {
          permissionNames.push(... binding.value);
        }
        useUserStore().permissionNames.some((name) => permissionNames.includes(name)) || el.remove();
      }
    });

当我这样使用:

// 组件
<div>{{ content }}</div>
<script type="ts" setup>
import { onMounted } from 'vue';
onMounted(() => console.log('auth content mounted.'))
</script>

// 引用组件
<div v-auth="['permission']">
  <MyComponent />
</div>

如果用户不拥有 permission 这个权限页面上不会显示这个元素。

当前的问题是:实际上组件还是被加载了之后又被 remove 掉,组件的 onMounted 生命周期函数已经被调用。

我希望自定义指令 v-auth 能像内置指令 v-if 一样跳过当前组件的加载过程,且不会触发 onMounted 生命周期函数请问如何做?

这里我也试过了 createdbeforeMount 但找不到办法来中断当前组件的加载。抛异常虽然会中断加载,但组件如果没有定义错误捕获则会中断整个页面的加载。

讨论数量: 8
ruke

google搜一搜好像听过弄这个指令的

6个月前 评论
zds
6个月前 评论
sanders (楼主) 6个月前
sanders (楼主) 6个月前
<template>
  <div v-if="hasPermission">
    <MyComponent />
  </div>
</template>

<script type="ts" setup>
import { useUserStore } from './userStore';

const userStore = useUserStore();
const hasPermission = userStore.permissionNames.includes('permission');
</script>

换个思路这么解决呢?

6个月前 评论
sanders (楼主) 6个月前

我能想到的方法,还是上面说的,即然项目里面已经大量使用了,那就仍然用v-if吧。但是对v-if里面的绑定值改一下,如改成globalPerssion()['myuser']这种,而globalPerssion这种可以全局注入一下。 这种全局替换也简单,工作量相对小一些。

1天前 评论

指令的设计决定了你没办法阻止子组件内部的运行。 v-if因为是个vue内部定制的。

1天前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!