| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- <template>
- <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners"></div>
- <svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
- <use :xlink:href="iconName" />
- </svg>
- </template>
- <script>
- // doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
- import { isExternal, isNumber } from '@/utils/validate';
- export default {
- name: 'SvgIcon',
- props: {
- size: {
- type: [String, Number],
- default: '',
- },
- width: {
- type: [String, Number],
- default: '1rem',
- },
- height: {
- type: [String, Number],
- default: '1rem',
- },
- iconClass: {
- type: String,
- required: true,
- },
- className: {
- type: String,
- default: '',
- },
- },
- computed: {
- _width() {
- return this._getSize(this.width, this.size);
- },
- _height() {
- return this._getSize(this.height, this.size);
- },
- isExternal() {
- return isExternal(this.iconClass);
- },
- iconName() {
- return `#icon-${this.iconClass}`;
- },
- svgClass() {
- const classes = ['svg-icon', this.iconClass];
- if (this.className) {
- classes.push(this.className);
- }
- return classes.join(' ');
- },
- styleExternalIcon() {
- return {
- mask: `url(${this.iconClass}) no-repeat 50% 50%`,
- '-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`,
- };
- },
- },
- methods: {
- /**
- * 获取尺寸
- * @param {String|Number} value
- * @param {String|Number} size
- */
- _getSize(value, size) {
- if (size) {
- if (isNumber(size)) return `${size}px`;
- return size;
- }
- if (isNumber(value)) {
- return `${value}px`;
- }
- return value;
- },
- },
- };
- </script>
- <style scoped>
- .svg-icon {
- width: v-bind(_width);
- height: v-bind(_height);
- overflow: hidden;
- vertical-align: -0.15em;
- fill: currentColor;
- }
- .svg-external-icon {
- display: inline-block;
- background-color: currentColor;
- mask-size: cover !important;
- }
- </style>
|