Using ionicons in Ionic Vue 3

Hello everyone,

I’m trying to find out what the default way is to showing ionicons in Ionic Vue. Im unable to use them when trying to import and also when using them inside other components (like icons inside input field or buttons).
What packages do I need, aside from “@ionic/vue”, or is that enough?

Looking forward to a reply.

With kind regards,
Nathan

i gave up for now and create components for each icon from the svg file

edit the svg, with some text editor

and make a little component

<template>
 <svg  style="width:24px;height:24px" viewBox="0 0 512 512">
<path d='M64 384h384v-42.67H64zm0-106.67h384v-42.66H64zM64 128v42.67h384V128z'/></svg>
</template>

<script>
  export default {}
</script>
<style>
  body 

put the path part of the svg file where the path part is above

then save this in components as the name.vue

then in your other code import it
and add to components,
then where you were using
use the name u imported

my little footer component using the icon components

<template>
<ion-footer>
  <ion-toolbar >
    <ion-buttons slot="start">
      <button ion-button  @click="back()">
        <!-- <ion-icon name="arrowback" ></ion-icon>-Back -->
        <arrowback/>-Back
      </button>
    </ion-buttons>

    <ion-buttons slot="end">
      <button ion-button @click="next()">Next-
         <!-- <ion-icon name="arrowforward"></ion-icon> -->
         <arrowforward/>
      </button>
    </ion-buttons>
  </ion-toolbar>
</ion-footer>
</template>
<script >

import { IonToolbar,   IonButtons, IonFooter,  }  from '@ionic/vue';
import  arrowback from './arrowback';
import  arrowforward from './arrowforward';

export default{
  name: 'Footer',
  components: { IonToolbar,   IonButtons, IonFooter,  arrowback, arrowforward} ,
  methods:{
    next(x){ console.log("next clicked type="+x);return x},
    back(x){ console.log("back clicked type="+x);return x},
  }
}
</script>

and the arrowforward component

<template>
 <svg  style="width:24px;height:24px" viewBox="0 0 512 512">
<path d='M464 256c0-114.87-93.13-208-208-208S48 141.13 48 256s93.13 208 208 208 208-93.13 208-208zm-212.65 91.36a16 16 0 01-.09-22.63L303.58 272H170a16 16 0 010-32h133.58l-52.32-52.73A16 16 0 11274 164.73l79.39 80a16 16 0 010 22.54l-79.39 80a16 16 0 01-22.65.09z'/></svg>
</template>

<script>
  export default {}
</script>
<style>
  body { padding: 1rem; }
</style>

i downloaded the svg icons from the ionicons web site library

@nathantaal, @sdetweil Unfortunately it is not documented. Here is an example of what you need to do. In the call to addIcons(), the keys in the object are the names you use in the name attribute of <ion-icon>, and the values are the icons you import from ionicons/icons. The import names of the icons are simple the camel case name as given when you click on an icon at https://ionicons.com/.

I added size and color just for demonstration. That is documented at https://ionicons.com/usage/.

<template>
  <ion-icon
    name="arrow-back"
    style="font-size: 24px; color: green"
  />
  <ion-icon
    name="forward"
    style="font-size: 24px; color: red"
  />
</template>

<script lang="ts">
import { IonIcon } from '@ionic/vue';
import { addIcons } from 'ionicons';
import { arrowBack, arrowForward } from 'ionicons/icons';

export default {
  components: {
    IonIcon
  },

  created() {
    addIcons({
      'arrow-back': arrowBack,
      forward: arrowForward
    });
  }
};
</script>

thanks

I was doing all that except for that created(){} wrapper around addIcons

another nice doc touch here would be

addIcons({
      template_name: import_name,
      template_name: import_name,
    });
if template name contains any special chars like -, ???? the name needs to be quoted

why do we need this redirection capability? my_name: importname?

wrapping in created() works… also moving the addIcons() into the export section… all the examples show it above

 <script>

  import { add } from "ionicons/icons";
  import { addIcons } from "ionicons";
  addIcons({
    "ios-add": add.ios,
    "md-add": add.md
  });

  export default {
    name: "HomePage",

@sdetweil @aparajita @nathantaal you are doing wayyyy too. much

<ion-button @click.prevent="addSlide">
  <ion-icon :icon="add"></ion-icon>
  add slide
</ion-button>

in the script section

<script lang="ts">
import {
  IonButton,
  IonIcon
} from "@ionic/vue";
import { add } from "ionicons/icons";
import { defineComponent, ref } from "vue";

export default defineComponent({
  name: "Tab1",
  components: { IonButton,  IonIcon },
  setup(_, ctx) {
    return { add  };
  },
});
</script>

you can find a more detailed example here

OH… the doc for icons is under BUTTONS… of COURSE!

also didn’t work here

commented out the created/addIcons,
added the icon name to the setup return, changed my template… nada

<template>
<ion-header>
 <ion-toolbar>
     <ion-buttons slot="start">
        <!-- <addicon v-if="getselectedRow(info.Type)<0"/> -->
        <!-- <editicon v-else/> -->
      <button ion-button icon-only @click="addeditClicked(1,getselectedRow(info.Type),info.Type,{true:'add',false:'edit'}[getselectedRow(info.Type)<0])">
        <ion-icon :name="getselectedRow(info.Type)<0 ? 'addCircleSharp':'search'"/>
      </button>
    </ion-buttons>
     <ion-title style="text-align: center;">{{info.Type}}s</ion-title>
    <ion-buttons slot="end">
      <button ion-button  icon-only @click="menu()">
        <ion-icon name="menu"></ion-icon>
      </button>
    </ion-buttons>
</ion-toolbar>
 <ion-toolbar>
  <ion-row>
    <ion-col  v-for="field in info.Fields" :key="field.Name" :size="field.width" class = " colb  center " >{{field.Name}}</ion-col>
  </ion-row>
 </ion-toolbar>
</ion-header>
</template>

<script >

import { IonHeader, IonToolbar, IonTitle, IonButtons, IonRow,IonCol,IonIcon}  from '@ionic/vue';


import { addCircleSharp , searchSharp, menuSharp} from "ionicons/icons";


export default{
  Name: 'Header',
  components: { IonHeader, IonToolbar, IonTitle,IonButtons,  IonRow,IonCol, IonIcon } ,
  methods:{
    addeditClicked(mode, row, type, imageName){ console.log("addedit clicked type="+type+" returning imagename="+imageName);return imageName},
    getselectedRow(x){ console.log("getselected clicked type="+x);return -1},
    menu(){ console.log("menu clicked"); return},
  },
  props: {
    info: { type: Object,
         Name: {
           type: String,
           default: function () {
             return 'Sample'
           }
         },
         Fields: {
           type: Array,
           default: function() {
             return [{Name: 'Test', width: 10}]
           }
         }
     }
  },
  setup(_,ctx){
   return {addCircleSharp}
  }
}
</script>

No shit???

Really you come here asking for help in the forum, because you don’t know what you are doing.

I really don’t believe that is an appropriate response to be using in any situation.

I don’t think it’s funny and not sure what you are implying with the clown face?

@nathantaal I replied to @aaronksaunders, not you.

in this situation, you have some quotes where they shouldn’t be

<ion-icon :icon="getselectedRow(info.Type)<0 ? addCircleSharp : search"/>

be sure you include the icons and also add them to the return statement

this is the page from the project that I tested with.

IF this doesnt work, please modify this gist and respond.

thanks

@aaronksaunders thanks… that works.

altho I don’t understand why the system can’t figure out that the thing is a literal (using :name) and look it up. this has worked in v1, v3 and v4 as literals.