NavLink.vue 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. <template>
  2. <router-link
  3. class="nav-link"
  4. :to="link"
  5. @focusout.native="focusoutAction"
  6. v-if="isInternal"
  7. :exact="exact"
  8. >{{ item.text }}</router-link>
  9. <a
  10. v-else
  11. :href="link"
  12. @focusout="focusoutAction"
  13. class="nav-link external"
  14. :target="target"
  15. :rel="rel"
  16. >
  17. {{ item.text }}
  18. <OutboundLink v-if="isBlankTarget"/>
  19. </a>
  20. </template>
  21. <script>
  22. import { isExternal, isMailto, isTel, ensureExt } from '../util'
  23. export default {
  24. props: {
  25. item: {
  26. required: true
  27. }
  28. },
  29. computed: {
  30. link () {
  31. return ensureExt(this.item.link)
  32. },
  33. exact () {
  34. if (this.$site.locales) {
  35. return Object.keys(this.$site.locales).some(rootLink => rootLink === this.link)
  36. }
  37. return this.link === '/'
  38. },
  39. isNonHttpURI () {
  40. return isMailto(this.link) || isTel(this.link)
  41. },
  42. isBlankTarget () {
  43. return this.target === '_blank'
  44. },
  45. isInternal () {
  46. return !isExternal(this.link) && !this.isBlankTarget
  47. },
  48. target () {
  49. if (this.isNonHttpURI) {
  50. return null
  51. }
  52. if (this.item.target) {
  53. return this.item.target
  54. }
  55. return isExternal(this.link) ? '_blank' : ''
  56. },
  57. rel () {
  58. if (this.isNonHttpURI) {
  59. return null
  60. }
  61. if (this.item.rel) {
  62. return this.item.rel
  63. }
  64. return this.isBlankTarget ? 'noopener noreferrer' : ''
  65. }
  66. },
  67. methods: {
  68. focusoutAction () {
  69. this.$emit('focusout')
  70. }
  71. }
  72. }
  73. </script>