You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击指向当前路径的RouterLink时如何触发函数?

检测所有导航尝试(含当前页面导航)的解决方案

针对你遇到的「点击指向当前页面的RouterLink时无法触发导航监听,导致下拉菜单无法关闭」的问题,以下是几种无需逐个给RouterLink加监听的可行方案:

方案1:重写路由跳转方法,全局捕获导航尝试

通过重写Vue Router的push和replace方法,在每次调用时触发自定义事件,不管导航是否成功跳转到新路由:

// router/index.js
import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory(),
  routes: [/* 你的路由配置 */]
})

// 保存原始跳转方法
const originalPush = router.push
const originalReplace = router.replace

// 重写push,触发自定义事件
router.push = function(location, onComplete, onAbort) {
  window.dispatchEvent(new CustomEvent('navigation-attempt'))
  return originalPush.call(this, location, onComplete, onAbort)
}

// 重写replace,触发自定义事件
router.replace = function(location, onComplete, onAbort) {
  window.dispatchEvent(new CustomEvent('navigation-attempt'))
  return originalReplace.call(this, location, onComplete, onAbort)
}

export default router

在下拉菜单组件中监听该事件,触发关闭逻辑:

// DropdownMenu.vue
import { onMounted, onUnmounted, ref } from 'vue'

export default {
  setup() {
    const isMenuOpen = ref(true)

    const closeMenuOnNavigation = () => {
      isMenuOpen.value = false
    }

    onMounted(() => {
      window.addEventListener('navigation-attempt', closeMenuOnNavigation)
    })

    onUnmounted(() => {
      window.removeEventListener('navigation-attempt', closeMenuOnNavigation)
    })

    return { isMenuOpen }
  }
}

方案2:全局监听RouterLink点击事件

通过自定义指令给所有RouterLink绑定点击监听,统一触发菜单关闭逻辑:

// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

const app = createApp(App)

// 定义全局指令,监听点击
app.directive('router-link-click', {
  mounted(el) {
    el.addEventListener('click', () => {
      window.dispatchEvent(new CustomEvent('navigation-attempt'))
    })
  }
})

// 给RouterLink自动应用该指令
const OriginalRouterLink = app.component('RouterLink')
app.component('RouterLink', {
  extends: OriginalRouterLink,
  directives: {
    'router-link-click': {}
  }
})

app.use(router).mount('#app')

菜单组件的监听逻辑和方案1一致,无需额外修改。

方案3:强制触发导航守卫

给所有RouterLink默认添加force属性,强制触发导航守卫(即使是当前路由),再在守卫中处理菜单关闭:

// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

const app = createApp(App)

// 重写RouterLink,默认开启force属性
const OriginalRouterLink = app.component('RouterLink')
app.component('RouterLink', {
  extends: OriginalRouterLink,
  props: {
    force: {
      type: Boolean,
      default: true
    }
  }
})

// 在导航守卫中触发菜单关闭
router.beforeEach(() => {
  window.dispatchEvent(new CustomEvent('navigation-attempt'))
  return true
})

app.use(router).mount('#app')

菜单组件同样通过监听navigation-attempt事件关闭菜单。


内容的提问来源于stack exchange,提问作者akopyl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 21:22:53