javascript - Vue 3 Dynamic Import based on Props - Stack Overflow

I am creating an icon ponent with unplugin-icon and in usual case i can import for examplescriptimp

I am creating an icon ponent with unplugin-icon and in usual case i can import for example

//script
import IconCopy from '~icons/prime/copy'
//template
<IconCopy/>

it works but it feels unconvenient to import one by one if we want ot use another icon so i create a dynamic ponent named Eunoicon.vue

<script setup>
const props = defineProps({
    icon : {type:String}
})
const from = `~icons/prime/${props.icon}`
const TheIcon = await import(/* @vite-ignore */from)
console.log('ti',TheIcon)
</script>
<template>
<TheIcon/>  
</template>

but when i try to import this to a ponent it throw error Uncaught (in promise) TypeError: Failed to resolve module specifier '~icons/prime/copy'. Is any suggestion for this approach or any icon library that provide simple way something like . I've tried vue font awesome but still it's not as simple as i want.

I am creating an icon ponent with unplugin-icon and in usual case i can import for example

//script
import IconCopy from '~icons/prime/copy'
//template
<IconCopy/>

it works but it feels unconvenient to import one by one if we want ot use another icon so i create a dynamic ponent named Eunoicon.vue

<script setup>
const props = defineProps({
    icon : {type:String}
})
const from = `~icons/prime/${props.icon}`
const TheIcon = await import(/* @vite-ignore */from)
console.log('ti',TheIcon)
</script>
<template>
<TheIcon/>  
</template>

but when i try to import this to a ponent it throw error Uncaught (in promise) TypeError: Failed to resolve module specifier '~icons/prime/copy'. Is any suggestion for this approach or any icon library that provide simple way something like . I've tried vue font awesome but still it's not as simple as i want.

Share Improve this question asked Aug 21, 2022 at 8:46 Matius Nugroho AryantoMatius Nugroho Aryanto 9014 gold badges21 silver badges48 bronze badges 2
  • The auto import feature is not enough: github./antfu/unplugin-icons#auto-importing? You can't do it fully dynamic tho because the icon is imported at build time and not runtime. – kissu Commented Aug 30, 2022 at 12:11
  • Check solutions here: stackoverflow./a/71179802/4378314 – Kalnode Commented Apr 12, 2023 at 23:02
Add a ment  | 

3 Answers 3

Reset to default 1

Unfortunately, it is currently impossible to create imports dynamically. I found myself in the same problem a few months ago. My solution was to treat the icons as SVGs and to create an import file attached to my project that looked like this:

interface SvgObject {
  [key: string]: Function;
}

export function importSvg(icon: string) {
  const svg = {
    "sliders-horizontal": () => {
      return '<line x1="148" y1="172" x2="40" y2="172" fill="none" /> <line x1="216" y1="172" x2="188" y2="172" fill="none" /> <circle cx="168" cy="172" r="20" fill="none" /> <line x1="84" y1="84" x2="40" y2="84" fill="none" /> <line x1="216" y1="84" x2="124" y2="84" fill="none" /> <circle cx="104" cy="84" r="20" fill="none" /> ';
    },
}

and to create a view ponent as below which thanks to a props would retrieve the icon corresponding to the given name.


<script setup lang="ts">
import { puted } from "vue";
import { importSvg } from "@/icons/importSvg";

interface Props {
  icon: string;
}

const IconComponent = importSvg(props.icon);

</script>

<template>
  <span>
    <svg
      xmlns="http://www.w3/2000/svg"
      viewBox="0 0 256 256"
      :aria-labelledby="icon"
      v-html="IconComponent"
    ></svg>
  </span>
</template>

<style>
...
</style>
<MyIcon icon="sliders-horizontal"/>

Of course creating the import file by hand would be cumbersome, so in my case I created a python script that takes a path to an SVG icon folder and processes each of the icons to minify them and create my import file automatically. The script works for icons from the phosphor icons library. You can find the code of the script and the Vue ponent in the github repo:

https://github./fchancel/Phosphor-icon-vue-ponent

Do not hesitate to be inspired, to modify it or to use it if you decide to use Phosphor icons

Had the same problem, if i needed an icon i had to import one by one. I found a solution; Imported the Material Icons lib on my main.ts file as:

import * as MuiIcons from '@mdi/js'

Then added as a globalProperty to:

APP = createApp(App);
APP.use(createPinia())
....and so on.
APP.config.globalProperties.$muicons = { ...MuiIcons };

Then i created a "MiscelaneousStore" on my store folder (pinia in my case).

    import { defineStore } from 'pinia';
    import { getCurrentInstance } from 'vue';

    export const useMiscelaneousStore = defineStore('useMiscelaneousStore',{
    state() {
      return {
        muicons: 
      getCurrentInstance()?.appContext?.config?.globalProperties?.$muicons,
        };
    },
      });

Then in my ponent i just import my store instance with all the icons as an object.

  const miscelaneousStore = useMiscelaneousStore();

  const materialIcons = puted((): any => {
    return miscelaneousStore.muicons;
  });

We could make an utils function or posable so we can access it wherever is needed.

HTML:

<svg-icon type="mdi" :path="materialIcons.mdiAccount" :size="48" style="color: red"></svg-icon>

VUE Tools for all icons.

I don't think you'll be able to dynamically import the icons but you can import them at the base of your application, which will make globally available.

I use Font Awesome, so the implementation may differ. See below:

FontAwesome.ts:

import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { library } from "@fortawesome/fontawesome-svg-core";
import {
    faUserSecret,
    faCommentAlt,
    faCog,
    faPowerOff,
    faMoon,
    faTrophy,
} from "@fortawesome/free-solid-svg-icons";

library.add(
    faUserSecret,
    faCommentAlt,
    faCog,
    faPowerOff,
    faMoon,
    faTrophy,
);

export default FontAwesomeIcon;

main.ts:

import { createApp, provide, h } from "vue";
import FontAwesomeIcon from "./assets/icons/fontAwesome";

import App from "./App.vue";

const app = createApp(App);
app.ponent("FontAwesomeIcon", FontAwesomeIcon);

Use icon:

<font-awesome-icon :icon="['fas', 'faTrophy']" />

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745665613a4639104.html

相关推荐

  • javascript - Vue 3 Dynamic Import based on Props - Stack Overflow

    I am creating an icon ponent with unplugin-icon and in usual case i can import for examplescriptimp

    4小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信