index.vue 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. <template>
  2. <div
  3. v-if="isExternal"
  4. :style="styleExternalIcon"
  5. class="svg-external-icon svg-icon"
  6. v-on="$listeners"
  7. />
  8. <svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
  9. <use :xlink:href="iconName" />
  10. </svg>
  11. </template>
  12. <script>
  13. // doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
  14. function isExternal(path) {
  15. return /^(https?:|mailto:|tel:)/.test(path);
  16. }
  17. export default {
  18. name: 'SvgIcon',
  19. props: {
  20. iconClass: {
  21. type: String,
  22. required: true
  23. },
  24. className: {
  25. type: String,
  26. default: ''
  27. }
  28. },
  29. computed: {
  30. isExternal() {
  31. return isExternal(this.iconClass);
  32. },
  33. iconName() {
  34. return `#icon-${this.iconClass}`;
  35. },
  36. svgClass() {
  37. if (this.className) {
  38. return `svg-icon ${this.className}`;
  39. }
  40. return 'svg-icon';
  41. },
  42. styleExternalIcon() {
  43. return {
  44. mask: `url(${this.iconClass}) no-repeat 50% 50%`,
  45. '-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
  46. };
  47. }
  48. }
  49. };
  50. </script>
  51. <style scoped>
  52. .svg-icon {
  53. width: 1em;
  54. height: 1em;
  55. vertical-align: -0.15em;
  56. fill: currentColor;
  57. overflow: hidden;
  58. }
  59. .svg-external-icon {
  60. background-color: currentColor;
  61. mask-size: cover !important;
  62. display: inline-block;
  63. }
  64. </style>