when i use vue3+vite+vite-svg-loader loop loading the svgs, but the browser only render the the first svg.
here the code:
MemuView.vue
<script setup>
import MenuItem from '@/components/common/MenuItem.vue'
import { getMenuByDeviceNo } from '@/network/api/terminalapi/common.js'
import { onMounted, ref } from 'vue'
const menuItems = ref([])
onMounted(async () => {
await getMenuByDeviceNo().then(
(res) => {
if (res.data && '0' === res.data.code) {
menuItems.value = res.data.data
console.log(menuItems)
}
},
(error) => {
console.error('getMenuByDeviceNo error', error)
}
)
})
</script>
<template>
<div class="menu">
<div class="menu-grid">
<MenuItem
v-for="item in menuItems"
:key="item.id"
:name="item.name"
:logo="item.logo"
:flag="item.flag"
/>
</div>
</div>
</template>
<style lang="less" scoped>
.menu-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
</style>
MemuItem.vue
<script setup>
import { ref } from 'vue'
const props = defineProps({
name: {
type: String,
require: true
},
logo: {
type: String,
require: true
},
flag: {
type: String,
require: true
}
})
const logoRef = ref(props.logo)
function triggerMenu() {}
</script>
<template>
<div class="service-item-wrap" @click="triggerMenu">
<div class="service-item">
<div class="big-menu">
<div class="ico-plane">
<svg-icon :name="logoRef"></svg-icon>
</div>
<div class="service-item-name" v-html="name"></div>
</div>
</div>
</div>
</template>
<style lang="less" scoped>
.service-item-wrap {
padding: 10px;
}
.ico-plane {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 10px;
.svg-container {
text-align: center;
}
}
.icon-controls {
display: flex;
justify-content: center;
margin-bottom: 10px;
button {
margin: 0 5px;
padding: 2px 8px;
background-color: #f0f0f0;
cursor: pointer;
&:hover {
background-color: #e0e0e0;
}
}
}
.service-item-name {
font-size: @font-size-base;
text-align: center;
}
</style>
SvgIcon.vue
<script setup>
import { shallowRef, watchEffect } from 'vue'
const props = defineProps({
name: {
type: String,
require: true
},
scale: {
type: Number,
default: 0.7
}
})
const SvgComponent = shallowRef(null)
const error = shallowRef(null)
watchEffect(async () => {
try {
SvgComponent.value = (await import(`@svg/${props.name}.svg?component`)).default
error.value = null
} catch (err) {
console.error('Failed to load SVG:', err)
error.value = err
SvgComponent.value = null
}
})
</script>
<template>
<div class="svg-container" :name="name" :style="{ transform: `scale(${scale})` }">
<component :is="SvgComponent" v-if="SvgComponent && !error" />
<span v-else>加载中...</span>
</div>
</template>
<style lang="less" scoped>
.svg-container {
display: inline-block;
width: 160px;
height: 160px;
transform-origin: center center;
svg {
width: 100%;
height: 100%;
visibility: visible !important;
opacity: 1 !important;
}
}
</style>
I want the browser to render the svg I load in a loop;But now the browser only renders the first svg I load, and when I change the order of loading the svg, the svg that wasn’t rendered before will also render
lizhaohui is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1