在开发中遇到一个需求,需要展示成就图标,考虑到从服务器请求会太慢,所以就想到用svg的方式来展示图标。所以就需要遍历渲染来添加svg图标。
// 此处的命名是随便起的,正常开发还是应该规范一点
<template>
<div class="containers">
<div id="container" ref="container" class="main-box"></div>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, watchEffect } from "vue";
const container = ref("");
// 在html文件中,图片资源是可以直接引用的,在开发中最好是用这种方式
const imgUrl = new URL("@/assets/images/common/bg1.svg", import.meta.url).href;
onMounted(() => {
watchEffect(() => {
container.value.innerHTML = "";
// 这就是需要遍历图标的位置坐标
const iconsData = [
{ name: "icon1", x: 0, y: 0 },
{ name: "icon2", x: -152, y: 0 },
{ name: "icon3", x: -304, y: 0 },
{ name: "icon4", x: -456, y: 0 },
{ name: "icon5", x: -608, y: 0 },
{ name: "icon6", x: -760, y: 0 },
];
iconsData.forEach((iconData) => {
const iconElement = document.createElement("svg");
iconElement.classList.add("item");
iconElement.style.backgroundImage = `url(${imgUrl})`;
iconElement.style.backgroundPosition = `${iconData.x}px ${iconData.y}px`;
container.value.appendChild(iconElement);
});
});
});
需要注意的是:在添加dom时,给每个dom都添加了类名为item,但是在样式中需要用:deep穿透一下,否则直接写item的样式是不会生效的。除非在添加dom时就添加了样式。如下:
iconsData.forEach((iconData) => {
const iconElement = document.createElement("svg");
// 这样添加的样式就不需要再额外添加样式,会直接生效
iconElement.style.width = "140px";
iconElement.style.height = "140px";
iconElement.style.borderRadius = "16px";
iconElement.classList.add("item");
iconElement.style.backgroundImage = `url(${imgUrl})`;
iconElement.style.backgroundPosition = `${iconData.x}px ${iconData.y}px`;
container.value.appendChild(iconElement);
});
上述是用svg实现dom的遍历添加,但添加完之后会发现页面会有卡顿,就是很卡的那种。查找一些帖子和资料,原因可能是:svg图虽然小,但包含大量的复杂路径和大量的节点,可能会对渲染和解析有影响,还在查找一些帖子。有知道的兄弟可以回复一下。
后续就尝试了一下用png图片来实现,结果也是可以的,而且没有svg的那种卡顿,就是正常的那流畅感。但用png时需要遍历添加的为div元素。效果跟svg的效果是一样的。
问题:有知道svg渲染之后会卡顿的问题和如何解决的兄弟,可以回复或者私信我解决,谢谢!!!