index.vue 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. <template>
  2. <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" />
  3. <svg v-else :class="svgClass" aria-hidden="true">
  4. <use v-if="color" :xlink:href="iconName" :fill="color" />
  5. <use v-else :xlink:href="iconName" />
  6. </svg>
  7. </template>
  8. <script setup>
  9. import { computed } from 'vue'
  10. const props = defineProps({
  11. iconClass: { type: String, required: true },
  12. className: { type: String, default: '' },
  13. color: { type: String, default: '#333' }
  14. })
  15. const isExternal = computed(() => {
  16. let isExternal = /^(https?:|mailto:|tel:)/.test(props.iconClass)
  17. return isExternal
  18. })
  19. const iconName = computed(() => {
  20. return `#icon-${props.iconClass}`
  21. })
  22. const svgClass = computed(() => {
  23. return props.className ? `svg-icon ${props.className}` : 'svg-icon'
  24. })
  25. const styleExternalIcon = computed(() => {
  26. return {
  27. mask: `url(${props.iconClass}) no-repeat 50% 50%`
  28. // "-webkit-mask": `url(${props.iconClass}) no-repeat 50% 50%`,
  29. }
  30. })
  31. </script>
  32. <style scoped>
  33. .svg-icon {
  34. width: 1em;
  35. height: 1em;
  36. vertical-align: -0.15em;
  37. fill: currentColor;
  38. overflow: hidden;
  39. }
  40. .svg-external-icon {
  41. background-color: currentColor;
  42. mask-size: cover !important;
  43. display: inline-block;
  44. }
  45. </style>