guard against same-route links

This commit is contained in:
lightling 2024-05-30 17:27:50 -04:00
parent 7944f6c5fd
commit c05143cf2c
3 changed files with 57 additions and 2 deletions

View file

@ -31,7 +31,9 @@ export class LinkEmbed extends HTMLElement {
if (_link.dataset?.href?.startsWith('/') && !!window.router) {
e.preventDefault()
const route = window.router.resolve({ path: _link.dataset.href })
window.router.push(route)
if (route.path !== window.router.currentRoute.value.path) {
window.router.push(route)
}
}
})
this._observers.href = {
@ -40,6 +42,12 @@ export class LinkEmbed extends HTMLElement {
const { element } = this._observers.href
element!.setAttribute('href', newVal)
element!.dataset.href = newVal
if (!!window.router) {
const route = window.router.resolve({ path: newVal })
if (route.path === window.router.currentRoute.value.path) {
element!.classList.add('current-route')
}
}
},
}
this._observers.target = {

View file

@ -1,8 +1,11 @@
<script setup lang="ts">
import { computed } from 'vue'
import { type HeaderEntry } from '@goldenwere/mackenzii-types'
import { useRouteStore } from 'src/routes'
import RouterLinkGuard from './router-link-guard.vue'
const props = defineProps<{
entry: HeaderEntry,
}>()
@ -29,7 +32,7 @@ li.header-entry
:target='entry.target || "_self"'
)
span {{ entry.displayName }}
router-link(
RouterLinkGuard(
v-else
:to='{ name }'
:target='entry.target || "_self"'

View file

@ -0,0 +1,44 @@
<script setup lang="ts">
import { computed, ref } from 'vue'
import { RouterLink, useRouter } from 'vue-router'
import { getCurrentRoute } from 'src/utilities/vuetils'
const props = defineProps({
// @ts-ignore
...RouterLink.props,
})
let route = ref(getCurrentRoute())
const router = useRouter()
const to = router.resolve(props.to)
const isExternalLink = computed(() => typeof props.to === 'string' && props.to.startsWith('http'))
const isCurrentRoute = computed(() => to.fullPath === route.value.fullPath)
router.afterEach(() => {
route.value = getCurrentRoute()
})
</script>
<template lang="pug">
span
a.external-link(
v-if='isExternalLink'
)
slot
span.current-route(
v-else-if='isCurrentRoute'
)
slot
router-link(
v-else
v-bind='$props'
custom
v-slot='{ href, navigate }'
)
a(
v-bind='$attrs'
:href='href'
@click='navigate'
)
slot
</template>