Vue-Router 可以处理来自普通锚点而不是路由器链接的点击吗?

dhe*_*man 5 vue-router vuejs2

我有一个场景,页面上有两个主要组件;一个类似框架的组件,包含许多应用程序的通用功能(包括书签/标签栏)和我的实际应用程序代码。

由于框架实际上并不拥有包含它的页面,因此它定义任何路由似乎是不正确的,但是当前页面可能会定义自己的路由,这些路由可能与这些链接之一匹配。在这种情况下,我想vue-router处理这些锚点点击并进行适当的导航,而不是重新加载整个页面。

这是一个简化的模板:

Frame(我的应用程序的外部依赖项):

<Frame>
   <TabStrip>
     <a href="//app1.foo.com/1245"></a>
     <a href="//app2.foo.com/account"></a>
     <a href="//app1.foo.com/2456"></a>
   </TabStrip>
   <slot></slot>
 <Frame>
Run Code Online (Sandbox Code Playgroud)

应用程序1:

<Frame>
  <App>You're looking at: {{ pageId }}!</App>
</Frame>
Run Code Online (Sandbox Code Playgroud)

因此,当app1从该选项卡条中单击任何域链接时,我希望我的路由定义app1选择它而不是导致页面加载。由于该组件归框架所有,我无权写入,<router-link>因为指向许多不同应用程序的链接可能在那里共存。

有什么想法吗?

One*_*yon 0

哎哟,这可是旧货啊!然而,由于当我研究这个问题时,这个问题在我的搜索结果中排名很高,所以我想我应该回答它。

我的用例与评论中的用例类似:我需要捕获<a>渲染中的正常链接v-html并通过路由器解析它们(应用程序正在渲染 Markdown,并进行轻微修改,在某些情况下会生成内部链接)。

我的解决方案需要注意的事项:

  • 我使用的是Vue3,而不是Vue2;最大的区别是,这是新的 Vue3 组合式单页面组件语法,但如果有必要,它应该很容易向后移植到 Vue2,因为它实际做的事情是标准 Vue。
  • 我删除了降价逻辑,因为它与这个问题没有任何关系。
  • 注意代码注释!您很可能需要设计自己的条件逻辑来识别需要路由的链接与其他链接(例如,如果原始问题中的应用程序具有Vue 应用程序未处理的同源链接,那么按原样复制/粘贴我的解决方案是行不通的)。
<script setup>
import { useRouter } from "vue-router"

const router = useRouter()

const props = defineProps({
  source: {
    type: String,
    required: true,
  },
})

function handleRouteLink(event) {
  const target = event.target
  // IMPORTANT! This is where you need to make a decision that's appropriate
  // for your application. In my case, all links using the same origin are
  // guaranteed to be internal, so I simply use duck-typing for the
  // properties I need and compare the origins. Logic is inverted because I
  // prefer to exit early rather than nest all logic in a conditional (pure
  // style choice; works fine either way, and a non-inverted conditional is
  // arguably easier to read).
  if (!target.pathname || !target.origin || target.origin != window.location.origin) {
    return
  }
  // We've determined this is a link that should be routed, so cancel
  // the event and push it onto the router!
  event.preventDefault()
  event.stopPropagation()
  router.push(target.pathname)
}
</script>

<template>
  <div v-html="source" @click="handleRouteLink"></div>
</template>

Run Code Online (Sandbox Code Playgroud)