Suresh
Suresh

Reputation: 967

vue-router : Creating a router-link with <a>

In my Vue SPA, I use vue-router with history mode. One of the components is vue-showdown. The vue-showdown generates HTML code dynamically. This could include links. The page reloads when a link is clicked. I would like to get these links work similar to how router-link works. I am wondering if there is any way we could reproduce the behavior of router-link using or other HTML tags.

If needed, I can update the markdown text with HTML tags as needed.

Upvotes: 0

Views: 605

Answers (1)

Julia
Julia

Reputation: 168

To avoid a full page reload with links, you should implement internal link delegation. It consists in adding an event listener to the root app component, so that all links referencing internal resources are delegated to Vue Router. Everything's well described and explained here: https://dennisreimann.de/articles/delegating-html-links-to-vue-router.html

The event listener would be:

mounted () {
  window.addEventListener('click', event => {
    // ensure we use the link, in case the click has been received by a subelement
    let { target } = event
    while (target && target.tagName !== 'A') target = target.parentNode
    // handle only links that do not reference external resources
    if (target && target.matches("a:not([href*='://'])") && target.href) {
      // some sanity checks taken from vue-router:
      // https://github.com/vuejs/vue-router/blob/dev/src/components/link.js#L106
      const { altKey, ctrlKey, metaKey, shiftKey, button, defaultPrevented } = event
      // don't handle with control keys
      if (metaKey || altKey || ctrlKey || shiftKey) return
      // don't handle when preventDefault called
      if (defaultPrevented) return
      // don't handle right clicks
      if (button !== undefined && button !== 0) return
      // don't handle if `target="_blank"`
      if (target && target.getAttribute) {
        const linkTarget = target.getAttribute('target')
        if (/\b_blank\b/i.test(linkTarget)) return
      }
      // don't handle same page links/anchors
      const url = new URL(target.href)
      const to = url.pathname
      if (window.location.pathname !== to && event.preventDefault) {
        event.preventDefault()
        this.$router.push(to)
      }
    }
  })
}

Upvotes: 2

Related Questions