Vue路由器 - 带有模板字符串中的链接

时间:2018-05-14 11:38:30

标签: vue.js vue-router

我从翻译API导入一些文本字符串。其中一些字符串包含HTML - 也包含链接。其中一些链接必须链接到内部路由器链接。例如some link。单击此链接将会正常工作 - 但它会重新加载应用程序,而不是推送SPA中的链接。

使导入/外部链接像vue-router链接一样的最佳方法是什么?

3 个答案:

答案 0 :(得分:0)

如果您希望点击由vue-router处理而不是重新加载页面,那么您真的应该使用<router-link>呈现链接。

否则,您可以拦截点击(通过委派)并手动导航到新路线:

<div @click="onClick">
  <!-- Render the HTML in here -->
  <a href="/foo/bar">Link</a>
</div>
onClick(e) {
  if (e.target.tagName === 'A') {
    e.preventDefault();

    // Manually navigate to the route
    this.$router.push(e.target.href);
  }
}

答案 1 :(得分:0)

尽管这是一个古老的问题,但我昨天遇到了同样的问题,可能会对将来的参考有所帮助。

尝试@Decade Moon的回答方式不能解决我的问题,因为window.location.origin附带了锚的href标签。

因此,如果我在https://www.example.com/about并想要导航至主页,则会得到该URL https://www.example.com/about/https://www.example.com,这不是预期的结果。

所以我的解决方案是在模板字符串中传递数据属性

const toHomepage = `<span data-href="/">Link to Homepage</span>`;

然后在我的组件中:

<p @click="linkTo" v-html="link"></p>

请参见 v-html指令将输出我的模板字符串。

linkTo(e) {
  if (e.target.dataset.href) {
    this.$router.push(e.target.dataset.href);
  }
}

答案 2 :(得分:0)

基于 https://dennisreimann.de/articles/delegating-html-links-to-vue-router.html 的 Decade 答案的更复杂版本:

function onClick(event: MouseEvent) {
  let target = event.target as HTMLElement
  while (target && target.tagName !== 'A') {
    target = target.parentNode as HTMLElement
  }
  const href = (target as HTMLLinkElement).href
  if (target && target.matches("a:not([href*='://'])") && href) {
    const { altKey, ctrlKey, metaKey, shiftKey, button, defaultPrevented } = event
    if (metaKey || altKey || ctrlKey || shiftKey) { return }
    if (defaultPrevented) { return }
    if (button !== undefined && button !== 0) { return }
    if (target && target.getAttribute) {
      const linkTarget = target.getAttribute('target') as string
      if (/\b_blank\b/i.test(linkTarget)) return
    }
    const url = new URL(href)
    const to = url.pathname
    if (window.location.pathname !== to && event.preventDefault) {
      event.preventDefault()
      router.push(to)
  }
}