<template> <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" /> <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 } from '@/utils/validate' export default { name: 'SvgIcon', props: { iconClass: { type: String, required: true }, className: { type: String, default: '' } }, computed: { isExternal() { return isExternal(this.iconClass) }, iconName() { return `#icon-${this.iconClass}` }, svgClass() { if (this.className) { return 'svg-icon ' + this.className } else { return 'svg-icon' } }, styleExternalIcon() { return { mask: `url(${this.iconClass}) no-repeat 50% 50%`, '-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%` } } } } </script> <style> .svg-icon { width: 1em; height: 1em; vertical-align: -0.15em; fill: currentColor; overflow: hidden; } .svg-external-icon { background-color: currentColor; mask-size: cover!important; display: inline-block; } </style>

2023-05-08by@1275680765-ObLB7&@GPT-4.Model: gpt-3.5
1275680765-ObLB7

<template>
<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="listeners"/><svgvelse:class="svgClass"ariahidden="true"von="listeners" /> <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 } from '@/utils/validate'

export default {
name: 'SvgIcon',
props: {
iconClass: {
type: String,
required: true
},
className: {
type: String,
default: ''
}
},
computed: {
isExternal() {
return isExternal(this.iconClass)
},
iconName() {
return #icon-${this.iconClass}
},
svgClass() {
if (this.className) {
return 'svg-icon ' + this.className
} else {
return 'svg-icon'
}
},
styleExternalIcon() {
return {
mask: url(${this.iconClass}) no-repeat 50% 50%,
'-webkit-mask': url(${this.iconClass}) no-repeat 50% 50%
}
}
}
}
</script>

<style>
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}

.svg-external-icon {
background-color: currentColor;
mask-size: cover!important;
display: inline-block;
}
</style>

Avatar
Avatar

This is a Vue.js component called "SvgIcon" that can render SVG icons. It accepts two props: "iconClass" (the name of the icon to render) and "className" (a CSS class to apply to the SVG element).

If the "iconClass" prop contains a URL (as determined by the "isExternal" computed property), the component will render an external icon with a mask set to that URL. Otherwise, it will render an SVG element with a "use" tag referencing an icon with an ID of "icon-" plus the "iconClass" prop.

The component has some default CSS styles that set the width, height, and fill of the SVG element. If a "className" prop is passed, it will be appended to the "svg-icon" class.

The component also has a "styleExternalIcon" computed property that sets the mask and -webkit-mask CSS properties for the external icon.

1275680765-ObLB7

举个例子怎么用

Avatar
Avatar

假设你有一个名为"my-icon.svg"的SVG文件,其中包含一个ID为"icon-heart"的图标。你可以在Vue.js组件中使用SvgIcon组件来渲染这个图标:

<template>
  <div>
    <svg-icon icon-class="heart" className="my-icon" />
  </div>
</template>

<script>
import SvgIcon from '@/components/SvgIcon'

export default {
  components: {
    SvgIcon
  }
}
</script>

这个例子中,SvgIcon组件会渲染一个SVG元素,其中包含一个"use"标签,其"xlink:href"属性值为"#icon-heart"。这将引用my-icon.svg文件中ID为"icon-heart"的图标。同时,SVG元素将具有"svg-icon"和"my-icon"类。

1275680765-ObLB7

我明白了,这个组件的作用是渲染SVG元素的,对么?

Avatar
Avatar

是的,你理解得很对。这个组件的作用是渲染SVG元素,让你可以在你的Vue.js应用中轻松地使用SVG图标。它会根据传入的属性值动态地生成SVG元素和图标内容。这样,你就无需手动编写SVG代码,也无需为每个图标都创建一个Vue.js组件。