Closed SirMishaa closed 2 years ago
Folder architecture is the following :
Basically, SVG component is here : frontend/components/swComponents/SwIcon.vue
Svg are in this folder: frontend/icons
but we have some icons in subfolder, so frontend/car_discounts
for example. (I think, that's maybe the tricky part)
Hi, does it work when you use a relative path?
await import(`../../icons/${this.name}.svg`)
Hi, does it work when you use a relative path?
await import(`../../icons/${this.name}.svg`)
No, I got the following error message :
Unknown variable dynamic import: ../../icons/car_discounts/car_lane_departure.svg
I think It's because the "name", is not a name, but sometime a path + name (yeah, bad naming, we're doing a lot of refactorings 😅)
Unknown variable dynamic import: ../../icons/car_discounts/car_lane_departure.svg
It seems that the file can't be found. Are you sure icons/car_discounts/car_lane_departure.svg
exists?
Yep : frontend/icons/car_discounts/car_lane_departure.svg
(My IDE generate the path, and I've double-checked)
I'm not sure the error message mean that, I don't know where does it come from
Any idea? :(
Can you try to use defineAsyncComponent
to see if that works?
import { defineAsyncComponent } from 'vue'
export default {
mounted () {
const svgObject = defineAsyncComponent(() => import(`/icons/${this.name}.svg?raw`))
}
}
I'm using this code to render icons from a subfolder dynamically
<template>
<IconComponent :viewBox="viewBox" />
</template>
<script setup lang="ts">
import type { Component } from 'vue'
import { IconName } from '@/types/IconName'
export interface IconProps {
name: IconName
fill?: Color
viewBox?: string | null
}
const props = withDefaults(defineProps<IconProps>(), {
fill: 'default',
viewBox: null,
})
const { loader } = createIconMap().get(props.name) ?? {}
const IconComponent = loader ? defineAsyncComponent(loader) : null
function getIconNameFromPath(path: string) {
const pathSplit = path.split('/')
const filename = pathSplit[pathSplit.length - 1] || ''
const iconName = filename.replace('.svg', '')
return iconName
}
function createIconMap() {
const importGlob = import.meta.glob('@/assets/icons/**/*.svg')
const iconMap = new Map<string, { loader: () => Promise<Component> }>([])
for (const path in importGlob) {
const iconName = getIconNameFromPath(path)
iconMap.set(iconName, { loader: importGlob[path] })
}
return iconMap
}
</script>
Sorry I haven't worked much with Vue 2 but I'm sure something for Vue 2 could be adapted from the code above.
Hello,
I have an issue when building the Vue (2.7) app:
We're using this component everywhere in our application. SwIcon.vue :
Like you can see, we have this import
await import(`/icons/${this.name}.svg?raw`);
which is working good in development.I guess the problem comes from the fact that during the build phase, since it is dynamic, it is not able to bundle the svg since it does not know them.
But then, how can I keep a similar component and make it work? Even if it has to bundle the whole icon's folder, it's not a big deal if it's lazy loaded.
Thanks in advance, I appreciate it ❤️
PS: I have already check #24, but I don't understand well for my case :/