Reputation: 967
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
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