| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 |
- <template>
- <span>
- <svg
- class="icon"
- aria-hidden="true"
- :style="{
- fontSize: computedSize,
- stroke: computedColor,
- fill: computedColor,
- display: 'inline-block',
- verticalAlign: 'middle',
- strokeWidth: strokeWidth + 'px',
- }"
- :width="computedSize"
- :height="computedSize"
- ref="svg"
- >
- <use :xlink:href="`#icon-${name}`" />
- </svg>
- </span>
- </template>
- <script lang="ts" setup>
- import { computed, ref, watch, watchEffect } from "vue";
- const props = defineProps<{
- name: string;
- percentage?: number;
- size?: string;
- color?: string;
- }>();
- // 计算属性:优先使用 props 传入的值,否则继承父级
- const computedSize = computed(() => props.size || "1em");
- const computedColor = computed(() => props.color || "currentColor");
- const svg = ref<SVGSVGElement | null>(null);
- const strokeWidth = ref<number>();
- const refreshStrokeWidth = () => {
- if (!props.percentage) {
- strokeWidth.value = undefined;
- return;
- }
- if (!svg.value) return;
- const symol = document.querySelector("#icon-" + props.name);
- if (!symol) return;
- const viewBox = symol.getAttribute("viewBox");
- if (!viewBox) return;
- const parts = viewBox.split(" ");
- if (parts.length === 4) {
- const size = Math.max(parseFloat(parts[2]), parseFloat(parts[3]));
- strokeWidth.value = (props.percentage / 100) * size; // 设定为视图高度的 2%
- }
- };
- watchEffect(refreshStrokeWidth);
- watch(props, () => setTimeout(refreshStrokeWidth), { deep: true, flush: "post" });
- </script>
|