nuxt3 在 directive中使用组合式 API(如 useFetch),代码的执行有问题

作者
2025-09-28阅读 30

1、问题背景

我想要实现当单击按钮的时候,根据设置片段该按钮是否需要用户登录,如果用户未登录的话,需要登录

这其中有一个点就是,如果token失效,我会使用refreshtoken来重新获取,也就有了问题描述中的在directive中使用useFetch的操作

这个是我的按钮的写法

<div v-needs-check="{ needValidate: true }" class="animation-follow-btn no-animation" @click="test()">
	<div class="follow-ctx show">
		关注
	</div> 
</div>

其中用到的是这个:v-needs-check="{ needValidate: true }"

我的redirective的写法是

// plugins/directives.js
export default defineNuxtPlugin((nuxtApp) => {
  
    // 自定义指令:需要登录校验
    nuxtApp.vueApp.directive('needs-check', {
      mounted(el, binding) {
        const onClick = async (event) => {

          const { needValidate = true } = binding.value || {}
          var isNeedLogin = false;

          //当前缓存的用户信息
          const customerStore = websiteStore.customerStore();
  
		  //这里进行过期的判断
		  ..........
		  
          if (needValidate && isNeedLogin) {
            // 阻止默认行为
            event.stopImmediatePropagation();
            event.preventDefault();
            event.stopPropagation();
  
            websiteStore.customerStore().showLoginModal = true;//显示登录对话框
            return false
          } 
        }
        el.addEventListener('click', onClick, true)
        // 保存引用以便更新
        el._needsCheckClick = onClick
      },
      unmounted(el) {
        el.removeEventListener('click', el._needsCheckClick, true)
      }
    })
  })

2、问题1-已补执行问题

首先我这边的useFetch一开始由于没有使用await,导致了异步执行的情况下,对于是否登录状态的判断有问题,这个好改,加上await相关的就可以了

3、问题2-click方法阻断问题(这个问题最终没有解决)

解决了异步问题,加下来的诉求就是我需要在directive阻断click方法的执行,只有当验证登录信息通过之后,才会继续执行click方法的函数

这里我用的是event.stopImmediatePropagation();

我在实际执行过程中发现,是不生效的

在我的调试过程中发现,如果我把useFetch相关的代码注释掉,则方法阻断是正常的,但是加上之后,阻断方法就失效了

查了下ai,发现在directive中使用useFetch是有问题的:

这是一个非常关键的提示 —— 说明你正在尝试在 Vue 的自定义指令(directive)中使用组合式 API(如 useFetch),而这在 Vue 的设计中是 不支持的

🔴 核心问题:useFetch 不能在 directive 中使用

  • useFetch 是 Vue 3 组合式 API(Composition API)中的一个组合函数(composable),它依赖于组件的 setup 上下文
  • 自定义指令(directive)是普通的 JavaScript 对象,没有 setup() 上下文,因此不能直接使用 useFetch、ref、reactive 等组合式 API
  • 如果你在 directive 中强行调用 useFetch,会抛出错误,或导致行为异常(比如事件监听失效、无法阻止 click 等)。

4、解决方法

我这里其实就是直接去掉了useFetch的处理。同时,登录接口中我同时返回了token和refreshtoken的过期时间

我在directive中只是做了时间的判断,如果两个时间同时过期的状态,才弹出登录页。

不再进行refreshtoken置换token的操作了

相当于在功能上是变相的妥协



全部评论