index.vue 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. <template>
  2. <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners"></div>
  3. <svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
  4. <use :xlink:href="iconName" />
  5. </svg>
  6. </template>
  7. <script>
  8. // doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
  9. import { isExternal, isNumber } from '@/utils/validate';
  10. export default {
  11. name: 'SvgIcon',
  12. props: {
  13. size: {
  14. type: [String, Number],
  15. default: '',
  16. },
  17. width: {
  18. type: [String, Number],
  19. default: '1rem',
  20. },
  21. height: {
  22. type: [String, Number],
  23. default: '1rem',
  24. },
  25. iconClass: {
  26. type: String,
  27. required: true,
  28. },
  29. className: {
  30. type: String,
  31. default: '',
  32. },
  33. },
  34. computed: {
  35. _width() {
  36. return this._getSize(this.width, this.size);
  37. },
  38. _height() {
  39. return this._getSize(this.height, this.size);
  40. },
  41. isExternal() {
  42. return isExternal(this.iconClass);
  43. },
  44. iconName() {
  45. return `#icon-${this.iconClass}`;
  46. },
  47. svgClass() {
  48. const classes = ['svg-icon', this.iconClass];
  49. if (this.className) {
  50. classes.push(this.className);
  51. }
  52. return classes.join(' ');
  53. },
  54. styleExternalIcon() {
  55. return {
  56. mask: `url(${this.iconClass}) no-repeat 50% 50%`,
  57. '-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`,
  58. };
  59. },
  60. },
  61. methods: {
  62. /**
  63. * 获取尺寸
  64. * @param {String|Number} value
  65. * @param {String|Number} size
  66. */
  67. _getSize(value, size) {
  68. if (size) {
  69. if (isNumber(size)) return `${size}px`;
  70. return size;
  71. }
  72. if (isNumber(value)) {
  73. return `${value}px`;
  74. }
  75. return value;
  76. },
  77. },
  78. };
  79. </script>
  80. <style scoped>
  81. .svg-icon {
  82. width: v-bind(_width);
  83. height: v-bind(_height);
  84. overflow: hidden;
  85. vertical-align: -0.15em;
  86. fill: currentColor;
  87. }
  88. .svg-external-icon {
  89. display: inline-block;
  90. background-color: currentColor;
  91. mask-size: cover !important;
  92. }
  93. </style>