index.vue 1.3 KB

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