Comments (9)
In Nuxt 3, you don't need neither vue-svg-loader
, nor vite-svg-loader
, but can instead create a custom component utilizing Vite's glob import:
<template>
<span v-if="icon" class="h-[1em] w-[1em]" v-html="icon" />
</template>
<script setup lang="ts">
const props = defineProps<{
name?: string
}>()
// Auto-load icons
const icons = Object.fromEntries(
Object.entries(import.meta.glob('~/assets/images/*.svg', { as: 'raw' })).map(
([key, value]) => {
const filename = key.split('/').pop()!.split('.').shift()
return [filename, value]
},
),
)
// Lazily load the icon
const icon = props.name && (await icons?.[props.name]?.())
</script>
from vue-svg-loader.
Thanks @cyruscollier . I switched to vite-svg-loader
which seems to work fine as well:
import svgLoader from 'vite-svg-loader'
export default defineNuxtConfig({
vite: {
plugins: [
svgLoader({
/* ... */
})
]
}
})
from vue-svg-loader.
@jerryjappinen I was able to get this working with Nuxt 3 using the0.17.0-beta.2
version of vue-svg-loader. My nuxt config looks like this:
export default defineNuxtConfig({
vite: false,
hooks: {
'webpack:config': (configs) => {
configs.forEach((config) => {
const svgRule = config.module.rules.find((rule) => rule.test.test('.svg'))
svgRule.test = /\.(png|jpe?g|gif|webp)$/
config.module.rules.push({
test: /\.svg$/,
use: ['vue-loader', 'vue-svg-loader'],
})
})
}
}
}
Let me know if that helps!
from vue-svg-loader.
@grindpride I could use dynamic component to load the svgs by this:
<template>
<component v-if="tag" :is="tag"></component>
</template>
<script>
import { shallowRef } from 'vue';
export default {
props: {
name: {
type: String,
required: true
},
},
setup(props) {
let tag = shallowRef('');
// Note this: `@` or `~` wont work
import(`../assets/svg/${props.name}.svg`).then(module => {
tag.value = module.default;
});
return {
tag
};
},
}
</script>
// Usage
<base-icon name="svg-name.svg"/>
More info: https://stackoverflow.com/questions/65950655/dynamic-component-in-vue3-composition-api
from vue-svg-loader.
Related: nuxt-community/svg-module#86
from vue-svg-loader.
@jerryjappinen But vite-svg-loader cannot into dynamic import. Like
setup(props) {
const currentIcon = computed(() => {
return defineAsyncComponent(() => import(`@/assets/icons/16/${props.name}.svg?component`))
}).value
return {
currentIcon
}
}
How do you import the icons component? Each one separately?
from vue-svg-loader.
@jerryjappinen But vite-svg-loader cannot into dynamic import. Like
setup(props) { const currentIcon = computed(() => { return defineAsyncComponent(() => import(`@/assets/icons/16/${props.name}.svg?component`)) }).value return { currentIcon } }
How do you import the icons component? Each one separately?
Yeah I usually import them as components, either each one separately or in one Icon
component which can then toggle the icon by prop (and do other things, like multiple icon states, rotations etc).
In a regular app/site with a limited set of commonly used icons I think it's fine. Haven't really needed dynamic imports that much.
from vue-svg-loader.
@grindpride I could use dynamic component to load the svgs by this:
<template> <component v-if="tag" :is="tag"></component> </template> <script> import { shallowRef } from 'vue'; export default { props: { name: { type: String, required: true }, }, setup(props) { let tag = shallowRef(''); // Note this: `@` or `~` wont work import(`../assets/svg/${props.name}.svg`).then(module => { tag.value = module.default; }); return { tag }; }, } </script> // Usage <base-icon name="svg-name.svg"/>
More info: https://stackoverflow.com/questions/65950655/dynamic-component-in-vue3-composition-api
Is there any security concern when providing the client access to telling server what path to load from?
from vue-svg-loader.
In Nuxt 3, you don't need neither
vue-svg-loader
, norvite-svg-loader
, but can instead create a custom component utilizing Vite's glob import:<template> <span v-if="icon" class="h-[1em] w-[1em]" v-html="icon" /> </template> <script setup lang="ts"> const props = defineProps<{ name?: string }>() // Auto-load icons const icons = Object.fromEntries( Object.entries(import.meta.glob('~/assets/images/*.svg', { as: 'raw' })).map( ([key, value]) => { const filename = key.split('/').pop()!.split('.').shift() return [filename, value] }, ), ) // Lazily load the icon const icon = props.name && (await icons?.[props.name]?.()) </script>
This component causes a recursive query for every svg that is in the ~/assets/images folder. In other words, every time this component is loaded, it re-queries ALL of the SVGs.
What I did was just loaded the icons into the state using pinia, then called the function to retrieve the SVG file data from the component instead (apologies for the tailwind css stuff, I'm in a time crunch):
AppStore.js
import { defineStore } from "pinia";
export const useAppStore = defineStore("AppStore", {
state: () => {
return {
icons: [Object],
};
},
actions: {
async fetchIcons() {
const i = Object.fromEntries(
Object.entries(
import.meta.glob("~/assets/svg/*.svg", { as: "raw" })
).map(([key, value]) => {
const filename = key.split("/").pop().split(".").shift();
return [filename, value];
})
);
this.icons = i;
},
},
});
SvgIcon.vue Component
<template>
<div class="pt-1">
<span v-if="icon" class="h-[1em] w-[1em]" v-html="icon" />
</div>
</template>
<script lang="ts">
import { useAppStore } from "../stores/AppStore.js";
export default defineComponent({
props: {
name: String,
},
async setup(props) {
const appStore = useAppStore();
var arr = Object.entries(appStore.icons).filter((i) => {
return i[0] === props.name;
});
const icon = await arr[0][1]?.().then((res: any) => {
return res;
});
return {
appStore,
icon,
};
},
});
</script>
from vue-svg-loader.
Related Issues (20)
- svgo options not working in webpack config
- [Question] Some objects in the SVG are being removed HOT 4
- Please create a new version to support svgo 2.x HOT 7
- SVG is missing parent's data-v attribute?
- Component is missing template or render function. HOT 1
- Syntax error on build HOT 4
- Relative module not found! HOT 4
- Module not found: Error: Can't resolve 'vue-loader-v16' HOT 1
- Security vulnerability - nth-check dependency HOT 1
- Syntax Error: NonErrorEmittedError: (Emitted value instead of an instance of Error) Error in parsing SVG: Non-whitespace before first tag. HOT 1
- Vuecli 5.x support HOT 7
- Loading svgs from different packages
- vue3 error HOT 5
- Is this project still being maintained? HOT 5
- Vue packages version mismatch
- nuxt3 can use? HOT 1
- [Vue warn]: Error in nextTick: "InvalidCharacterError: Failed to execute 'createElement' on 'Document' HOT 1
- Allow loading SVG images from HTML without breaking the current syntax (Nuxt) HOT 2
- Mark the component as Raw or use shallowRef
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from vue-svg-loader.