SvgIcon.vue 2.0 KB

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