nuxt / icon

The <Icon> component, supporting Iconify, Emojis and custom components.
https://stackblitz.com/edit/nuxt-icon-playground?file=app.vue
MIT License
864 stars 37 forks source link

Custom Local Collections invalid #162

Closed hmingv closed 1 month ago

hmingv commented 1 month ago

Following the steps in the document, I expected to use the Icon component to display a custom SVG Icon, but it failed.

https://stackblitz.com/edit/nuxt-icon-playground-t9ezmw?file=app.vue

hmingv commented 1 month ago

image

hmingv commented 1 month ago

Okay, this feature has only been supported since version 1.0.0, so I misunderstood it.

LordLumineer commented 1 month ago

But it would be nice to have a warning of some sort in the documentation..

ndt080 commented 1 month ago

If it wasn't for this issue, I would have been trying for over an hour to figure out why my custom icons don't appear.

LordLumineer commented 1 month ago

I have forced the install of v1.0.0-beta.4, in dev it works~ish, the cutom icons don't necessarily load the first time and the refresh of the page after having rendered the element where the icon is tends to make them show. I haven't tested with beta.5 or with build or generate.

ndt080 commented 1 month ago

@LordLumineer I abandoned this library in favor of my own implementation.

Folder assets/icons File iconSet.ts

export const IconSet = {
  'arrow/chevron-down': defineAsyncComponent(() => import('./arrow/chevron-down.svg')),
  'arrow/chevron-up': defineAsyncComponent(() => import('./arrow/chevron-up.svg')),
} as Record<string, ReturnType<typeof defineAsyncComponent>>;

Folder components File BaseIcon.vue

<script lang="ts" setup>
import { IconSet } from '@icons/IconSet';

interface BaseIconProps {
  name: keyof typeof IconSet;
  width?: string | number;
  height?: string | number;
}

const props = withDefaults(defineProps<BaseIconProps>(), {
  name: '',
  width: 'auto',
  height: '',
});

const styles = computed(() => ({
  width: props.width 
     ? props.width + (!Number.isNaN(Number(props.width)) ? 'px' : '') 
      : undefined,
  height: props.height
    ? props.height + (!Number.isNaN(Number(props.height)) ? 'px' : '')
    : undefined,
}));
</script>

<template>
  <suspense>
    <component :is="IconSet[name] || 'span'" :style="styles" v-bind="$attrs" />
  </suspense>
</template>

it works faster and the code is cleaner

Important! You need to install the package vite-svg-loader

Mychen3 commented 2 weeks ago

@LordLumineer我放弃了这个库而选择我自己的实现。

文件夹 assets/icons 文件 iconSet.ts

export const IconSet = {
  'arrow/chevron-down': defineAsyncComponent(() => import('./arrow/chevron-down.svg')),
  'arrow/chevron-up': defineAsyncComponent(() => import('./arrow/chevron-up.svg')),
} as Record<string, ReturnType<typeof defineAsyncComponent>>;

文件夹组件 文件 BaseIcon.vue

<script lang="ts" setup>
import { IconSet } from '@icons/IconSet';

interface BaseIconProps {
  name: keyof typeof IconSet;
  width?: string | number;
  height?: string | number;
}

const props = withDefaults(defineProps<BaseIconProps>(), {
  name: '',
  width: 'auto',
  height: '',
});

const styles = computed(() => ({
  width: props.width 
     ? props.width + (!Number.isNaN(Number(props.width)) ? 'px' : '') 
      : undefined,
  height: props.height
    ? props.height + (!Number.isNaN(Number(props.height)) ? 'px' : '')
    : undefined,
}));
</script>

<template>
  <suspense>
    <component :is="IconSet[name] || 'span'" :style="styles" v-bind="$attrs" />
  </suspense>
</template>

它运行得更快,代码更干净

重要!您需要安装**vite-svg-loader软件包**

Thank you, I think I know what to do now