123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- <template>
- <div class="svg-container" v-html="processedSvg" :style="containerStyle"></div>
- </template>
- <script setup>
- import { ref, watch, computed } from 'vue';
- const props = defineProps({
- // SVG图片的URL
- svgUrl: {
- type: String,
- required: true
- },
- // 要设置的颜色
- color: {
- type: String,
- default: '#262626'
- },
- // SVG宽度
- width: {
- type: String,
- default: '16px'
- },
- // SVG高度
- height: {
- type: String,
- default: '16px'
- }
- });
- const rawSvg = ref('');
- const processedSvg = ref('');
- const error = ref(null);
- // 容器样式
- const containerStyle = computed(() => ({
- width: props.width,
- height: props.height,
- display: 'inline-block'
- }));
- // 加载SVG
- const loadSvg = async () => {
- try {
- error.value = null;
- const response = await fetch(props.svgUrl);
-
- if (!response.ok) {
- throw new Error(`无法加载SVG: ${response.statusText}`);
- }
-
- rawSvg.value = await response.text();
- } catch (err) {
- error.value = err.message;
- console.error('加载SVG时出错:', err);
- }
- };
- // 处理SVG并修改颜色
- const updateSvgColor = () => {
- if (!rawSvg.value) return;
-
- // 创建临时DOM元素来处理SVG
- const parser = new DOMParser();
- const doc = parser.parseFromString(rawSvg.value, 'image/svg+xml');
- const svgElement = doc.querySelector('svg');
-
- if (!svgElement) {
- processedSvg.value = rawSvg.value;
- return;
- }
-
- // 移除可能影响颜色的属性
- svgElement.removeAttribute('fill');
- svgElement.removeAttribute('stroke');
-
- // 添加CSS类以便通过样式控制
- svgElement.classList.add('dynamic-svg');
-
- // 修改所有路径和形状的颜色
- const elements = svgElement.querySelectorAll('path, circle, rect, polygon, polyline, line, ellipse');
- elements.forEach(el => {
- // 保存原始颜色以便可能的恢复
- if (!el.dataset.originalFill) {
- el.dataset.originalFill = el.getAttribute('fill') || '';
- }
- if (!el.dataset.originalStroke) {
- el.dataset.originalStroke = el.getAttribute('stroke') || '';
- }
-
- // 设置新颜色
- if (el.dataset.originalFill && el.dataset.originalFill !== 'none') {
- el.setAttribute('fill', props.color);
- }
- if (el.dataset.originalStroke && el.dataset.originalStroke !== 'none') {
- el.setAttribute('stroke', props.color);
- }
- });
-
- // 将处理后的SVG转换回字符串
- const serializer = new XMLSerializer();
- processedSvg.value = serializer.serializeToString(svgElement);
- };
- // 监听属性变化并重新加载/处理SVG
- watch(() => props.svgUrl, loadSvg, { immediate: true });
- watch(() => props.color, updateSvgColor);
- watch(rawSvg, updateSvgColor);
- </script>
- <style scoped>
- .svg-container {
- overflow: hidden;
- }
- /* 备用样式,在直接修改属性不生效时使用 */
- :deep(.dynamic-svg) {
- width: 100%;
- height: 100%;
- }
- /* 可以根据需要添加更多样式 */
- </style>
|