Files
NSG_PORTAL_V2/directives/v-interpolate.ts
T
Duong Truong Phong 3b435e22ea phongdt:header footer
2024-05-30 22:58:33 +07:00

53 lines
1.2 KiB
TypeScript

import type { ObjectDirective } from 'vue'
type InterpolationElement = HTMLElement & {
$componentUpdated?: () => void
$destroy?: () => void
}
export const vInterpolate: ObjectDirective<InterpolationElement> = {
mounted(el) {
const links = Array.from(el.getElementsByTagName('a')).filter((linkEl) => {
const href = linkEl.getAttribute('href')
if (!href) {
return false
}
return isInternalLink(href)
})
addListeners(links)
// cleanup
el.$componentUpdated = () => {
removeListeners(links)
nextTick(() => addListeners(links))
}
el.$destroy = () => removeListeners(links)
},
updated: (el) => el.$componentUpdated?.(),
beforeUnmount: (el) => el.$destroy?.()
}
function navigate(event: Event) {
const target = event.target as HTMLElement
const href = target.getAttribute('href')
event.preventDefault()
return navigateTo(href)
}
function addListeners(links: HTMLAnchorElement[]) {
links.forEach((link) => {
link.addEventListener('click', navigate, false)
})
}
function removeListeners(links: HTMLAnchorElement[]) {
links.forEach((link) => {
link.removeEventListener('click', navigate, false)
})
}
function isInternalLink(href?: string) {
return href?.startsWith('/')
}