index.vue 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  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 name="SvgIcon">
  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. display: inline-block;
  35. width: 1em;
  36. height: 1em;
  37. vertical-align: -0.15em;
  38. fill: currentColor;
  39. overflow: hidden;
  40. }
  41. .svg-external-icon {
  42. background-color: currentColor;
  43. mask-size: cover !important;
  44. display: inline-block;
  45. }
  46. </style>