Estoy tratando de convertir mi aplicación Vue2/Webpack a Vue3/Vite.
En Vue2/Webpack, esto funciona:
<div v-html="require('!!html-loader!../../assets/icons/' + this.icon + '.svg')"></div>El cargador HTML se agrega con:
"html-loader": "1.3.2", En Vue3/Vite esto arroja el error: ReferenceError: require is not defined
Busqué un ejemplo de cómo hacer esto, pero no veo cómo hacerlo sin saber el nombre del archivo en el momento de la compilación. ¿Es eso posible?
También puede usar la técnica Lazy Load Components con defineAsyncComponent de Vue3 - 🔗 ref.
o import() como se muestra en @ tony19 en esta respuesta :
<script> const getServiceIcon = async iconName => { const module = await import(/* @vite-ignore */ `../assets/svg/${iconName}.svg`) return module.default.replace(/^\/@fs/, '') } export default { data() { return { icon: null, iconName: 'icon1', // icon1.svg } }, watch: { iconName: { async handler(iconName) { this.icon = await getServiceIcon(iconName) }, immediate: true, }, }, } </script> <template> <button @click="iconName = 'icon2'">Change to another SVG</button> <img :src="icon" height="72" width="72" /> </template>Puede echar un vistazo al complemento vite-svg-loader y cargar archivos SVG como componentes de Vue.
Simplemente creando un componente donde cargarás los iconos. Usando la API de composición aquí.
<template> <i v-html="icon" /> </template> <script lang="ts" setup> import { ref, watchEffect } from 'vue'; const props = defineProps(['icon', 'loading', 'src']); const icon = ref(); const path = props.src ? props.src : ''; const file = `${path}icon-${props.icon}`; const modules = import.meta.glob('../../assets/icons/**/*.svg', { as: 'raw' }); function getViews(path: any) { return modules['../../assets/icons/' + path + '.svg']; } const getServiceIcon = async () => { return getViews(file); }; watchEffect(async () => (icon.value = await getServiceIcon())); </script>Esto le permitirá incluso diseñar su SVG usando css, tailwind, etc.
El uso:
<UiIcon icon="NAME" class="w-8 fill-current text-red-500"/>Hecho.